Javascript: Can't control parent of descendant nodes

401 Views Asked by At

I'm creating elements (level 1) dynamically which in turn create elements (level 2) themselves. However, the children of level 2 elements have "body" as their parent.

In the HTML code below, the content if spotAd2 is created by my function createNode(). It's a Google Ad Sense tag. However, the Google Ad Sense tag create elements that went directly under "body". I need them to by under tnDiv1.

function createNode( t, // type.
                     tn, // if type is element, tag name.
                     a, // if type is element, attributes.
                     v, // node value or text content
                     p, // parent
                     f ) // whether to make dist the first child or not.
{
  n = null;

  switch( t )
  {
    case "element":
      n = document.createElement( tn );

      if( a )
      {
        for( k in a )
        {
          n.setAttribute( k, a[ k ] );
        }
      }
    break;

    case "text":
    case "cdata_section":
    case "comment":
      n = document.createTextNode(v);
    break;
  }
  if ( p )
  {
  if( f )
  {
    p.insertBefore( n, p.firstChild );
  }
  else
  {
    p.appendChild( n );
  }
}
  return n;
}

spotAd2 = document.getElementById("spotAd2");
n1 = createNode("element", "div", {"id":"tnDiv1"}, "\n" , spotAd2, true);
n2 = createNode("element", "script", {"type":"text\/javascript"}, "\n" , n1, false);
n3 = createNode("comment", "", null, "\n" +
"google_ad_client = \"pub-0321943928525350\";\n" +
"/* 728x90 (main top) */\n" +
"google_ad_slot = \"2783893649\";\n" +
"google_ad_width = 728;\n" +
"google_ad_height = 90;\n" +
"//\n" , n2, false);
n4 = createNode("element", "script", {"type":"text\/javascript","src":"http:\/\/pagead2.googlesyndication.com\/pagead\/show_ads.js"}, "\n" , n1, false);

--- Result:

<body>

<table cellspacing="2" cellpadding="2" border="1">
<tbody><tr>
<td>Oel ngati kemeie</td>
<td>Kamakto niwin</td>
</tr>
<tr>
<td>The ad:</td>
<td>

  <div id="spotAd2">
    <!-- Created by createNode() -->
    <div id="tnDiv1">
      <script type="text/javascript">
        google_ad_client = "pub-0321943928525350";
        /* 728x90 (main top) */
        google_ad_slot = "2783893649";
        google_ad_width = 728;
        google_ad_height = 90;
      </script>
      <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
    </div>
    <!-- Created by createNode() -->
  </div>

</td>
</tr>
<tr>
<td>txopu ra'a tsi, tsamsiyu</td>
<td>teyrakup skxawng</td>
</tr>
</tbody></table>

<!-- Created by adsense tag, need these to be under tnDiv1 -->
<script src="http://pagead2.googlesyndication.com/pagead/expansion_embed.js"></script>
<script src="http://googleads.g.doubleclick.net/pagead/test_domain.js"></script>
<script>google_protectAndRun("ads_core.google_render_ad", google_handleError, google_render_ad);</script>
<ins style="border: medium none ; margin: 0pt; padding: 0pt; display: inline-table; height: 90px; position: relative; visibility: visible; width: 728px;">
  <ins style="border: medium none ; margin: 0pt; padding: 0pt; display: block; height: 90px; position: relative; visibility: visible; width: 728px;">
    <iframe width="728" scrolling="no" height="90" frameborder="0" vspace="0" style="left: 0pt; position: absolute; top: 0pt;" src="http://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-0321943928525350&amp;output=html&amp;h=90&amp;slotname=2783893649&amp;w=728&amp;lmt=1273708979&amp;flash=10.0.45&amp;url=http%3A%2F%2Fkenshin.katanatechworks.com%2Ftest%2FadsBrowserSide.php&amp;dt=1273708980294&amp;shv=r20100422&amp;correlator=1273708980298&amp;frm=0&amp;ga_vid=695691836.1273708981&amp;ga_sid=1273708981&amp;ga_hid=1961182006&amp;ga_fc=0&amp;u_tz=480&amp;u_his=2&amp;u_java=1&amp;u_h=1080&amp;u_w=1920&amp;u_ah=1052&amp;u_aw=1920&amp;u_cd=24&amp;u_nplug=5&amp;u_nmime=38&amp;biw=1394&amp;bih=324&amp;fu=0&amp;ifi=1&amp;dtd=955&amp;xpc=Jl67G4xiq6&amp;p=http%3A//kenshin.katanatechworks.com" name="google_ads_frame" marginwidth="0" marginheight="0" id="google_ads_frame1" hspace="0" allowtransparency="true">
    </iframe>
  </ins>
</ins>
<!-- Created by adsense tag, need these to be under tnDiv1 -->
</body>
1

There are 1 best solutions below

0
iamhappycoder On

Ok, after much needed sleep (been awake for almost 24 hours) my head cleared up and was able to analyze the problem better (with some helpful inputs from my colleagues).

I realized that the culprit is document.write() and should have asked something like this:

JavaScript - controlling the insertion point for document.write

Which lead me to a whole lot of solutions.

I then came up with this prototype:

document.write = function(str)
{
    div = document.createElementNS("http://www.w3.org/1999/xhtml","div");
    div.innerHTML = str;

    var nodes = div.childNodes;
    while ( nodes.length )
    {
        document.getElementById("spotAd2").appendChild( nodes[0] );
    }
};

Voila! The AdSense ad showed up where I want it to be.

With a little bit of refinement, I can turn this into a generic solution.