Reputation: 8046
I currently am a developer on a site which uses pushstate for page transitons.
The site uses Google DFP Ads, which refresh on each page transition / route
I am noticing a problem in Internet Explorer
I am on Windows 7, IE10.
googletag.pubads().refresh(GOOGLE_ADS);
Will remove entries on the window.history stack, thus causing the use of the back button to have incorrect entries.
Quick example
Add Entries onto the history stack
console.log(window.history.length) // 3
window.history.pushState({}, 'title', '/page_1');
window.history.pushState({}, 'title', '/page_2');
window.history.pushState({}, 'title', '/page_3');
window.history.pushState({}, 'title', '/page_4');
console.log(window.history.length) // 7
Refresh Ads
googletag.pubads().refresh(GOOGLE_ADS);
Check History Length Again
console.log(window.history.length) // 3
If i were to press the back button, it would go to the page before the landing page.
Anyone else notice this issue in IE? Looking at DFP source, it references window.history a couple times.
Upvotes: 4
Views: 1217
Reputation: 239
As i posted on DFP Help Forum: https://productforums.google.com/forum/#!topic/dfp/9BsgVtKTU9A
I have working solution, where i use jQuery.
if(typeof googletag !== 'undefined' && typeof googletag.pubads !== 'undefined') {
if(adsCloned === false) {
var $dfpIframe = $('#div-gpt-ad-1477269112222-0').find('iframe'); // this is ad id that you use in googletag.defineSlot()
$dfpIframe.each(function (i, v) {
var $clone = $(v).clone();
$(v).replaceWith($clone);
});
adsCloned = true;
}
googletag.pubads().refresh();
}
before that you have to define var adsCloned = false;
The reason why it works, is when you refresh the iframe that is inserted after page load (in this case cloned iframe) the history entry wont add to the IE.
edit: if it won't work for you, try to delete if statememt:
if(typeof googletag !== 'undefined' && typeof googletag.pubads !== 'undefined') {
var $dfpIframe = $('#div-gpt-ad-1477269112222-0').find('iframe'); // this is ad id that you use in googletag.defineSlot()
$dfpIframe.each(function (i, v) {
var $clone = $(v).clone();
$(v).replaceWith($clone);
});
googletag.pubads().refresh();
}
The above code wont't work - my mistake. But working solution for me is to destroy whole googletag variable and call whole code again.
First call of dfp script looks like this (note googletag.pubads().disableInitialLoad(); and gads.id = 'dfpHeadScript';):
// Doubleclick
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
(function() {
var gads = document.createElement('script');
gads.async = true;
gads.id = 'dfpHeadScript';
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);
})();
googletag.cmd.push(function() {
enovatis.dfpSlots.push( googletag.defineSlot('...', [240, 400], 'div-gpt-ad-1').addService(googletag.pubads()) );
enovatis.dfpSlots.push( googletag.defineSlot('...', [[960, 100], [750, 100]], 'div-gpt-ad-2').addService(googletag.pubads()) );
googletag.pubads().enableSingleRequest();
googletag.pubads().collapseEmptyDivs();
googletag.pubads().disableInitialLoad();
googletag.enableServices();
});
googletag.cmd.push(function(){
googletag.pubads().refresh();
});
and the method for refresh ads is:
var dfpInterval = null;
var $dfpTop = $('#div-gpt-ad-1');
var $dfpLeft = $('#div-gpt-ad-2');
function refreshDfp() {
$dfpTop.empty();
$dfpLeft.empty();
googletag = {};
googletag.cmd = [];
$('#dfpHeadScript').remove();
(function() {
var gads = document.createElement('script');
gads.async = true;
gads.id = 'dfpHeadScript';
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);
})();
googletag.cmd.push(function() {
enovatis.dfpSlots.push( googletag.defineSlot('...', [240, 400], 'div-gpt-ad-1').addService(googletag.pubads()) );
enovatis.dfpSlots.push( googletag.defineSlot('...', [[960, 100], [750, 100]], 'div-gpt-ad-2').addService(googletag.pubads()) );
googletag.pubads().enableSingleRequest();
googletag.pubads().collapseEmptyDivs();
googletag.pubads().disableInitialLoad();
googletag.enableServices();
window.clearInterval(dfpInterval);
dfpInterval = window.setInterval(function(){
if(typeof googletag.pubads !== 'undefined'){
window.setTimeout(function(){
googletag.pubads().refresh();
}, 75);
window.clearInterval(dfpInterval);
}
}, 75);
});
}
I call it with: refreshDfp.apply(window);
and everything works well.
The only disadvantage of this approach is that we sending more request to google each time.
Upvotes: 0
Reputation: 211
We had the exact same problem. In IE10 and IE11 pushstate is pretty much useless if you're using DFP.
However, we did come up with a solution. It's not pretty, but it works.
Instead of loading the ad, we insert an iframe. Within that iframe the ad is loaded as usual. However, the refresh()-method cannot be used inside that iframe, the same issue would still occur. But what you can do when the ads are loaded in an iframe is to refresh the entire iframe. By doing so the ads with be refreshed and the pushstate-functionality will stay intact.
Pretty nasty, but it works. Since loading ads in an iframe is bad for several reasons, we only do this in IE10 and IE11.
Upvotes: 2
Reputation: 20882
I experience the same issue with IE10 and IE11 - very disappointing.
For what its worth I have raised a bug with Microsoft that can be seen here:
If you have time add your comes to the bug to give it more weight towards a hopeful fix.
Adam
Upvotes: 1
Reputation: 21
I have exactly the same problem, even running the ads in an iframe with a different domain still causes history to be lost. I believe it is something to do with IE handling iframe src changes as history events, but basically using google ads totally breaks pushstate in IE. Only way I found to fix was to not use Google ads.
Upvotes: 2