PDA

View Full Version : Using JS to dynamically position & run a script



geekcoach
01-26-2010, 02:52 AM
My overall challenge is to make up for what I consider to be a design flaw in how Google Ad Manager works. What I am trying to accomplish is create a way for an advertiser to randomly rotate through whichever ad formats are available, rather than get locked into a particular ad slot location.

This has required several steps, most of which I've been able to work out by myself, and now I'm down to what I expect is the last big issue.

Because Google Ad Manager pairs up the highest priority advertiser with the first loaded ad slot script, the most important task was to randomize the load order of the scripts. Doing this, however, necessitates pairing up those scripts with the appropriate space set aside for them on the page, more or less after the fact.

The code I'm having trouble with is the part where I try to move the node containing the active script to the its desired location and is showing just about every permutation of result except the one that I want, depending on browser.



var moveithere = document.getElementById(newmodid);
moveithere.appendChild(divinloader[i]);
moveithere.appendChild(scriptelement[i]);


Not surprisingly, IE breaks as soon as it gets to this point and nothing happens with the divinloader[i] node OR the scriptelement[i] node - I have seen some references that it's not likely to like this and perhaps some recommendations about how to handle it, so I'm not too concerned about that just yet.

Firefox doesn't throw any kind of an error, but neither does the scriptelement[i] node do anything at all, even though the divinloader[i] node migrates to where I want it.

Chrome comes the closest to working - the script runs, but not in the location that I want.

Although I don't expect it's been an exhaustive search, I have tried a number of other approaches and this one has seemed to get me the closest to the desired result with the simplest coding. As to what's currently acceptable coding and what's not, I won't pretend to have a clue.

To see the full code in action, what it does, what I'm trying to do and to check for errors (likely) or offer suggestions on how I could get there more easily just use the following - I've substituted simpler code so that you don't have to pull down the actual Google Ad Manager scripts but it seems to work exactly the same and shows what I'm trying to do anyway. Hopefully there aren't any unnecessary artifacts still present.



<html>
<head>
<title>Testing arrayed dynamic randomized script loading</title>
</head>

<body>

<!-- PUT THIS TAG IN DESIRED LOCATION OF SLOT ATFRectangle-Main
-->
<div id="atfrectangle-outer"> Tell 'em TIO sent you (rectangle) <div id="atfrectangle-inner">
</div> </div>
<!-- END OF TAG FOR SLOT ATFRectangle-Main
-->

<!-- PUT THIS TAG IN DESIRED LOCATION OF SLOT ATFWideSkyscaper-Main
-->
<div id="atfwideskyscaper-outer"> Tell 'em TIO sent you (skyscaper)<div id="atfwideskyscaper

-inner">
</div></div>
<!-- END OF TAG FOR SLOT ATFWideSkyscaper-Main
-->

<!-- PUT THIS TAG IN DESIRED LOCATION OF SLOT FullBanner-Main
-->
<div id="fullbanner-outer"> Tell 'em TIO sent you (banner)<div id="fullbanner-inner">
</div></div>
<!-- END OF TAG FOR SLOT FullBanner-Main
-->


<h1>Load up the array with ad formats</h1>

<script type = "text/JavaScript">


// create an array to hold information about the various ad formats
var adformat = new Array();

// load the array with the appropriate ad format data
adformat[0] = "FullBanner";
adformat[1] = "ATFRectangle";
adformat[2] = "ATFWideSkyscaper";

// make a notation about what is coming next (and show successful conclusion of previous

steps)
document.write("<h2>Order for the ad formats as loaded into the array</h2>");


// declare the variable to use for counting
var i = 0;

// begin looping through as many times as needed to go through entire array and write out

each ad format
for (i in adformat) {
document.write("<p>" + adformat[i] + "<br> </p>");
}
// end loop for writing out the list of ad formats loaded into the array


// randomize the order of the ad format list
randadload = adformat.sort (function(){
return 0.5-Math.random()
})

// make a notation about what is coming next (and show successful conclusion of previous

steps)
document.write("<h2> Order for the ad formats after randomization</h2>");

// declare the variable to use for counting
var i = 0;

// begin looping through as many times as needed to go through entire array and write out

each ad format in the new list order
for (i in randadload) {
document.write("<p>" + randadload[i] + "<br> </p>");
}
// end loop for writing out the randomized list of ad formats


// make a notation about what is coming next (and show successful conclusion of previous

steps)
document.write("<h2>Creating dynamic module names and script-calling variables</h2>");



// declare variables that might be needed

// create an array to hold module names
modname = new Array();

// create array to hold the names of the google script, partial and full
googscript = new Array();
fullgoogscript = new Array();

// create an array to hold the id to be used for the script loader element
loaderid = new Array();
scriptloaderid = new Array();

// create an array to hold the id for the module
modid = new Array();

// create an array to hold the name of the id for the script inside module
modscriptid = new Array();

// create an array to hold the name of the id for the outer DIV tag
divoutloader = new Array();

// create an array to hold the name of the id for the inner DIV tag
divinloader = new Array();

scriptnodeloader = new Array();
scriptelement = new Array();

// declare the variable to use for counting
var i = 0;

// create a variable to hold the current script number
var scriptnum = 0;

// begin looping through number of elements in the array
for (i in randadload) {

// advance the counter by one increment for each iteration in the loop
scriptnum ++;

// create a script name based on the name of the ad format
googscript[i] = randadload[i] + "-Main";

// change the ad format name to all lower case
loadlc = randadload[i].toLowerCase();

// create a module name based on the name of the ad format
modname[i] = "main" + loadlc;

// create a DIV id name for the loader element based on the name of the ad format
loaderid[i] = loadlc + "_loader";
// create a script id name for the loader element based on the name of the ad format
// scriptloaderid[i] = loadlc + "_scriptloader"'

// create a DIV id name for the inner DIV tag based on the name of the ad format
modid[i] = loadlc + "-inner";
// create a script id name based on the name of the ad format
modscriptid[i] = loadlc + "-script";

//write out all the names just created to check for successful completion and for

accuracy
document.write("<p>Module name is " + modname[i] + " and script name is " +

googscript[i] + " and loader ID is " + loaderid[i] + " and module id is " + modid[i] + "<br>

</p>");


// create a DIV tag to load the script into
divinloader[i] = document.createElement("div");
divinloader[i].setAttribute("id", loaderid[i]);
divinloader[i].style.display="block";

// use the DIV loader to write out the status of the scripts (ultimately hope to LOAD

the scripts)
divinloader[i].innerHTML = "<p>Pretend loading script " + scriptnum + " now... <br>

GA_googleFillSlot(" + googscript[i] + ");" ;

// create the content to be included in the script to be loaded
fullgoogscript[i] = 'document.write("<p> This is actually a real script loading ' +

googscript[i] + ' as a stand-in for a Google script loading " + randadload[i] + "

advertisements.</p>");';


// creating a script element
scriptnodeloader[i] = document.createTextNode(fullgoogscript[i]);

scriptelement[i] = document.createElement("script");
scriptelement[i].type = "text/javascript";
scriptelement[i].setAttribute("id", scriptloaderid[i]);
scriptelement[i].appendChild(scriptnodeloader[i]);

// if this line runs, results in [object HTML scriptelement]
// divinloader[i].innerHTML = scriptelement[i];


newmodid = modid[i];
newmodscriptid = modscriptid[i]


// want to use this to move the script up to its final location
// document.getElementById(newmodid).appendChild(divinloader[i]);
// document.getElementById(newmodscriptid).appendChild(scriptelement[i]);


var moveithere = document.getElementById(newmodid);
moveithere.appendChild(divinloader[i]);
moveithere.appendChild(scriptelement[i]);

}
// end looping through elements in the array



</script>



</body>

</html>


I appreciate any insights you can provide - feel free to call me an idjit if necessary, but please be specific if you do.

Thanks,

Kimm

geekcoach
02-04-2010, 03:03 AM
All these views and no responses, looks like perhaps I've stumped the experts here. Hopefully someone else can get something useful out of what I *have* accomplished with this code.

OTOH, if I've simply not been clear enough about my problem, please let me know as I'd still appreciate any help you might have to offer and I'm happy to clarify any questions you might have about what I'm doing and why.

Thanks,

Kimm

Old Pedant
02-04-2010, 03:42 AM
Well, FWIW, MSIE 7 breaks before the point you indicated.

It breaks on this line:
scriptelement[i].appendChild(scriptnodeloader[i]);

with the error:
Unexpected call to method or property access.

But other than that...

The only dumbass suggestion I can think of would be to *absolutely* position your slots. Then you can mix up their order and google presumably puts the first ad into the first slot it encounters in order of <div> appearance on the page.

If you used server-side code to generate the page, then mixing up the order on the page would be easy. Shouldn't think it would be too hard even in JS if you used document.write to create them.

The trick, of course, is getting the absolute positions where you want them.

But maybe even that isn't too hard.

Suppose you put them all at top=0, left=0 initially. Then you put dummy blank div placeholders the *actual* locations where you want them on the page as part of the normal flow of the page. And then you just "find" the placeholders and position the absolute divs on top of them.

No?

The only google ad stuff I've been involved with has all been simple listing style stuff, so no experience with your banner/rectangle/skyscraper stuff. So maybe I completely misunderstand the problem.

Old Pedant
02-04-2010, 04:15 AM
Yep. Seems to work just fine.


<html>
<head>
<script>
function yowser()
{
var node = document.getElementById("HERE");
var x = 0;
var y = 0;
while ( node != null )
{
x += node.offsetLeft;
y += node.offsetTop;
node = node.offsetParent;
}
var ad = document.getElementById('ad1');
ad.style.left = x + "px";
ad.style.top = y + "px";
}
</script>
</head>
<body onload="setTimeout('yowser()',1000)">
<div id="ad1" style="position: absolute; width: 130px; height: 250px; border: solid red 5px;">
<script type="text/javascript"><!--
google_ad_client = "pub-1886035884398677";
/* 120x240, created 10/30/08 */
google_ad_slot = "8774357809";
google_ad_width = 120;
google_ad_height = 240;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>


<div id="ad2" style="position: absolute; top: 500px; left: 50px; width: 135px; height: 135px; border: solid red 5px;">
<script type="text/javascript"><!--
google_ad_client = "pub-1886035884398677";
/* 125x125, created 10/30/08 */
google_ad_slot = "2164369780";
google_ad_width = 125;
google_ad_height = 125;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
Okay, this is the normal body layout...
<br/><br/>
Some stuff goes here and here...
<br/><br/>
<div id="HERE" style="position: relative; width: 130px; height: 250px; margin-left: 450px;"></div>
<br/>
And so on...
</body></html>

The setTimeout is in there just so you can see it happen.

I didn't bother repositioning the second ad, but obviously it's just cloning code.

Old Pedant
02-04-2010, 04:18 AM
I would want to use server-side code to produce the various position:absolute divs (all with top:0, left:0, though it doesn't really matter since they'll get moved) in random order.

But that's me.

Old Pedant
02-04-2010, 08:44 AM
Ehhh...I figured out the easy way to do this all in JS (the randomizing of the order of the various sized ads). It's really pretty simple.

Still think driving it from server-side is even easier, but ask about it if you don't have any server-side capabilities.

You give me the three sample ad-pullers and I can show it, I betcha.