Google GPT - googletag.cmd queue re-order - google-dfp

Could somebody help me with the Google GPT googletag.cmd queue re-order issue?
(1) in the home HTML page, I have this:
googletag.cmd.push(function() { defineSlot1(); });
googletag.cmd.push(function() { defineSlot2(); });
googletag.cmd.push(function() { defineSlot3(); });
googletag.cmd.push(function() { defineSlot4(); });
(2) in attached js, I dynamically added:
googletag.cmd.push(function() { defineSlot5(); });
(3) So right now in the googletag.cmd queue, the sequence like this:
[slot1, slot2, slot3, slot4, slot5];
My question is, how to move the slot5 to the second place after slot1, like this:
[slot1, slot5, slot2, slot3, slot4];
In https://developers.google.com/doubleclick-gpt/reference,
googletag.commandArray only has push(f) method, and the googletag.cmd is not a standard array.
How to do this? Thanks.

Google GPT library is loaded in async mode and it initially defines googletag.cmd as a regular Array.
<script type='text/javascript'>
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
(function() {
var gads = document.createElement('script');
gads.async = true;
gads.type = 'text/javascript';
var useSSL = 'https:' == document.location.protocol;
gads.src = (useSSL ? 'https:' : 'http:') +
'//www.googletagservices.com/tag/js/gpt.js';
var node = document.getElementsByTagName('script')[0];
node.parentNode.insertBefore(gads, node);
})();
</script>
When the main library gets downloaded (it occurs in parallel with page rendering) it converts the initially defined array into a custom object (https://developers.google.com/doubleclick-gpt/reference#googletag.CommandArray) so you indeed won’t be able to modify it.
Back to your question:
If you use
googletag.pubads().enableSingleRequest() (https://developers.google.com/doubleclick-gpt/reference#googletag.PubAdsService_enableSingleRequest) all of your adslots will be queried and displayed on the first googletag.display(…) call.
If you don’t use enableSingleRequest an individual query will be sent each time you call googletag.display(…) for a particular ad slot regardless of its definition order
Considering p.1 and p.2 I don’t get why would you care the order of slots definition.
Anyway, if you really need it you might define your own queue variable
window.custom_cmd = [];
and use it instead of googletag.cmd throughout your page so it would look as follows:
custom_cmd.push(function() {
// regular defineSlot(…) calls
});
and then somewhere after your attached js file is loaded just
// reorder it or whatever else
…
// copy your queue into the regular queue
for (var i = 0; i < custom_cmd.length; i++) {
googletag.cmd.push(custom_cmd[i]);
}
this code would trigger the ad calls

Related

DOMContentLoaded is not firing

I am trying to create a chrome extension but having problems with DOMContentLoaded as it is not firing.
Note: my code was taken from a different website.
Basically, I have create an HTML file with a button:
<head>
<title>GTmetrix Analyzer</title>
<script src="popup.js"></script>
</head>
<body>
<h1>GTmetrix Analyzer</h1>
<button id="checkPage">Check this page
now!</button>
</body>
And this is the JS file (popup.js):
document.addEventListener
('DOMContentLoaded',
function() {
console.log("f")
var checkPageButton =
document.getElementById('checkPage');
checkPageButton.addEventListener('click',
function() {
chrome.tabs.getSelected(null,
function(tab) {
d = document;
var f = d.createElement('form');
f.action = 'http://gtmetrix.com/analyze.html?bm';
f.method = 'post';
var i = d.createElement('input');
i.type = 'hidden';
i.name = 'url';
i.value = tab.url;
f.appendChild(i);
d.body.appendChild(f);
f.submit();
});
}, false);
}, false);
I added the console.log event in order to check if the event is executed, so this is how I verified that it isn't working.
I also added run_at": "document_start
but then I got
Uncaught TypeError: Cannot read property 'addEventListener' of null
For the "click" event, so I guess that the event was triggered before the button was created.
Help, please!

Facebook Tracking of In-Page Events with Conversion Pixel Code

Full disclosure - I'm not a programmer, but I'm the only one in my organisation who might be able to get this working. Can anyone help with the following please?
I'm trying to use Facebook's conversion pixel code to track certain button clicks on our site. Facebook's developer docs give the following instructions for tracking in-page events:
After the base code snippet is installed, you can track in-page actions, such as clicks on a button, by making a _fbq.push('track') call for the conversion pixel through registering different event handlers on an HTML DOM element. For example:
function trackConversionEvent(val, cny) {
var cd = {};
cd.value = val;
cd.currency = cny;
_fbq.push(['track', '<pixel_id>', cd]);
}
<button onClick="trackConversionEvent('10.00','USD');" /
The problem I'm facing is it's not clear to me what Facebook means by "the base code snippet". My initial assumption was that it's the conversion pixel code they give you to install in the head section of the page, i.e.
<!-- Facebook Conversion Code -->
<script>(function() {
var _fbq = window._fbq || (window._fbq = []);
if (!_fbq.loaded) {
var fbds = document.createElement('script');
fbds.async = true;
fbds.src = '//connect.facebook.net/en_US/fbds.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(fbds, s);
_fbq.loaded = true;
}
})();
window._fbq = window._fbq || [];
window._fbq.push(['track', '<pixel_id>', {'value':'0.00','currency':'USD'}]);
</script>
<noscript><img height="1" width="1" alt="" style="display:none" src="https://www.facebook.com/tr?ev=<pixel_id>&cd[value]=0.00&cd[currency]=USD&noscript=1" /></noscript>
However, if I install the above on our page it loads/fires the conversion pixel code each time the page loads rather than on the button click (presumably because it's typically used on a thank you/confirmation page). Can anyone shed any light on this for me? I believe I understand where to position the onClick code to associate it with a button click but I'm struggling to understand where I need to position the trackConversionEvent code and what the base code snippet is. Through testing, I know that removing the following lines from the larger code snippet stops the pixel from loading:
window._fbq = window._fbq || [];
window._fbq.push(['track', '<pixel_id>', {'value':'0.00','currency':'USD'}]);
but I'm not sure if that's actually what I need to do. Do I for example, need to replace those two lines with the trackConversionEvent code so that the pixel doesn't fire when the page loads but the onClick code actually functions instead when the button is clicked?
Many thanks in advance for any pointers or suggestions.
This should work, I.ve just tested on a blog based on WP.
<!-- Facebook Conversion Code -->
<script>(function() {
var _fbq = window._fbq || (window._fbq = []);
if (!_fbq.loaded) {
var fbds = document.createElement('script');
fbds.async = true;
fbds.src = '//connect.facebook.net/en_US/fbds.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(fbds, s);
_fbq.loaded = true;
}
})();
window._fbq = window._fbq || [];
</script>
<noscript><img height="1" width="1" alt="" style="display:none" src="https://www.facebook.com/tr?ev=<pixel_id>&cd[value]=0.00&cd[currency]=USD&noscript=1" /></noscript>
<!-- End Of Facebook Conversion Code -->
This is the event handler that you could bind to any button, link or any DOM element::
function trackConversionEvent(val, cny) {
var cd = {};
cd.value = val;
cd.currency = cny;
_fbq.push(['track', '<pixel_id>', cd]);
}
<button onClick="trackConversionEvent('10.00','USD');"

Why is childNodes not working in this script?

I am new to JS and trying to learn some basic stuff. I have spent hours on this but i don't think it should be that difficult. For some reason, my computer is not recognizing that I am asking for childNodes.
This is a simply script that is only trying to count the number of li tags I have. I know there are other ways to do this but i am trying to learn this way.
<title>To-Do List</title>
<script>
function findComments(){
var bodyTag = document.getElementsByTagName("ol");
var count = 0;
for(var i=0;i<bodyTag.childNodes.length;i++){
if(bodyTag.childNodes[i].nodeType == 1){
count++;
}
}
alert(count);
}
window.onload = findComments;
</script>
<!--List is declared-->
<ol id="toDoList">
<!--List Items are created-->
<li>Mow the lawn</li>
<li>Clean the windows</li>
<li>Answer your email</li>
</ol>
<!--Main paragraph-->
<p id="toDoNotes">Make sure all these are completed by 8pm so you can watch the game on TV!</p>
<script>
</script>
getElementsByTagName returns an array, you need to retrieve its first element (and change the name from bodyTag to olTag or something since it's not the body tag and confused the heck out of me trying to make sense of your code)
function findComments(){
var ol = document.getElementsByTagName("ol")[0];
var count = 0;
for(var i=0;i<ol.childNodes.length;i++){
if(ol.childNodes[i].nodeType == 1){
count++;
}
}
alert(count);
}
And here's what you really should do now that you know what's wrong with your code
var ol = document.getElementsByTagName("ol")[0];
var liCount = ol.getElementsByTagName("li").length;

DFP: Getting the current click-through URL

I am setting up a DFP for multiple site, we have a set of line items and for each of it's creatives, the current click through is going to example.com (our own .com site), but since we are running multiple TLDs, we also want the click through URL to change accordingly. For example, when the ads is being displayed in the .jp, the click through should go to .jp.
In the DFP API reference, there's a function to change the click-through URL: http://support.google.com/dfp_premium/bin/answer.py?hl=en&answer=1650154&expand=adslot_details#setClickUrl
But in order to change our click-through URL, we also need to know what's the current URL. Example case: we need to get http://www.example.com/products/1 from the DFP adSlot in order to change it to http://www.example.jp/products/1.
I ran through trial and error using chrome web JS console and found a getClickUrl() function in the adSlot class, but it keeps returning empty string, for example:
googletag.defineSlot("/1234/Test_300x250", [300, 250], 'div-1').getClickUrl();
googletag.defineSlot("/1234/Test_300x250", [300, 250], 'div-1').addService(googletag.pubads()).getClickUrl();
Anyone have experience with this?
If you have control over the creative, I think it would be a lot easier to do by passing custom variables. You use the setTargeting method to pass a custom variable. So your client-side code to display the ad would look like this:
googletag.defineSlot("/1234/Test_300x250", [300, 250], 'div-1').setTargeting('region','jp');
And then in your HTML creative you use a pattern macro to replace part of the click-through URL.
<a href="http://www.example.%%PATTERN:region%%">
<img src="http://www.example.%%PATTERN:region%%/image.jpeg">
</a>
And DFP will replace the macro with whatever value you pass via setTargeting.
I haven't found a super simple way to do this - but it is possible.
Basically you can override an internal function in DFP and capture the content of the ad (and the URL) by getting into the DOM of the iframe.
Here is an example which should alert the URL of the ad (I've only tested this in chrome, so it may need tweaking to work in multiple browsers)
<html>
<head>
<title>DFP test</title>
<script type='text/javascript'>
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
(function() {
var gads = document.createElement('script');
gads.async = true;
gads.type = 'text/javascript';
var useSSL = 'https:' == document.location.protocol;
gads.src = (useSSL ? 'https:' : 'http:') +
'//www.googletagservices.com/tag/js/gpt.js';
var node = document.getElementsByTagName('script')[0];
node.parentNode.insertBefore(gads, node);
})();
</script>
<script type="text/javascript">
googletag.cmd.push(function() {
var slot1 = googletag.defineSlot('/12345678/Test_300x250', [300, 250], 'div-gpt-ad-1340819095858-0').addService(googletag.pubads());
slot1.oldRenderEnded = slot1.renderEnded;
slot1.renderEnded = function(){
alert(document.getElementById('div-gpt-ad-1340819095858-0').getElementsByTagName('iframe')[0].contentWindow.document.getElementsByTagName('a')[0].href.replace(/^.*&adurl=/,''));
slot1.oldRenderEnded();
};
googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
</script>
</head>
<body>
<div id='div-gpt-ad-1340819095858-0' style='width:266px; height:115px;'>
<script type='text/javascript'>
googletag.cmd.push(function() {
googletag.display('div-gpt-ad-1340819095858-0');
});
</script>
</div>
</body>
</html>
If you are using jQuery its a bit nicer to use something like:
$(adUnit).find('iframe:first').contents().find('a')
Any questions let me know.

Javascript horizontal slider not working

I'm using an old version of the Slidedeck Plugin (v.1.4.5) and I have a javascript problem with one of the skins I'm using. More precisely, the horizontal slides are stitched together and I can't figure out how to fix this. I want each slide to be independent, without any content from the next or previous slide to be seen on the active slide.
You can see in the screenshot from below that the middle slide has visible content from the previous and next slide, which obviously I don't want to be visible.
I should mention that I have very limited knowledge of javascript / jQuery, and I suspect it's a js problem because the CSS is the same for all skins - the only variable is the script used by each skin.
You can see the slider behavior on this website and below is the full script used for the slider skin. I would appreciate any help on this. To change the slides click on each slide arrow from left or right side, or you can use the directional keys on the keyboard.
(function($){
SlideDeckSkin['fullwidth-sexy'] = function(slidedeck){
var ns = 'fullwidth-sexy';
var elems = {};
elems.slidedeck = $(slidedeck);
elems.frame = elems.slidedeck.closest('.skin-' + ns);
// Disable spines as this skin is not meant to function with spines on
elems.slidedeck.slidedeck().setOption('hideSpines', true);
elems.frame.append('PreviousNext');
elems.slidedeck.append('<div class="' + ns + '-mask left"></div><div class="' + ns + '-mask right"></div>');
elems.frame.find('.sd-' + ns + '-nav').bind('click', function(event){
event.preventDefault();
var $this = $(this);
elems.slidedeck.slidedeck().options.pauseAutoPlay = true;
if($this.hasClass('prev')){
elems.slidedeck.slidedeck().prev();
} else {
elems.slidedeck.slidedeck().next();
}
});
};
$(document).ready(function(){
$('.skin-fullwidth-sexy .slidedeck').each(function(){
if(typeof($.data(this, 'skin-fullwidth-sexy')) == 'undefined' || $.data(this, 'skin-fullwidth-sexy') == null){
$.data(this, 'skin-fullwidth-sexy', new SlideDeckSkin['fullwidth-sexy'](this));
}
});
});
})(jQuery);
The following might work, but it is hard to test without an example of what you are trying to do.
What I did is added a unique number to the ns variable (for namespace I assume.) This number is passed to the callback of the each function. (doc)
(function($){
SlideDeckSkin['fullwidth-sexy'] = function(slidedeck,uniqueName){
var ns = 'fullwidth-sexy'+uniqueName;
var elems = {};
elems.slidedeck = $(slidedeck);
elems.frame = elems.slidedeck.closest('.skin-' + ns);
// Disable spines as this skin is not meant to function with spines on
elems.slidedeck.slidedeck().setOption('hideSpines', true);
elems.frame.append('PreviousNext');
elems.slidedeck.append('<div class="' + ns + '-mask left"></div><div class="' + ns + '-mask right"></div>');
elems.frame.find('.sd-' + ns + '-nav').bind('click', function(event){
event.preventDefault();
var $this = $(this);
elems.slidedeck.slidedeck().options.pauseAutoPlay = true;
if($this.hasClass('prev')){
elems.slidedeck.slidedeck().prev();
} else {
elems.slidedeck.slidedeck().next();
}
});
};
$(document).ready(function(){
$('.skin-fullwidth-sexy .slidedeck').each(function(n){
if(typeof($.data(this, 'skin-fullwidth-sexy')) == 'undefined' || $.data(this, 'skin-fullwidth-sexy') == null){
$.data(this, 'skin-fullwidth-sexy', new SlideDeckSkin['fullwidth-sexy'+n](this,n));
}
});
});
})(jQuery);