I'm having trouble displaying Google DFP ads inside of jQuery-UI tabs (loaded via ajax). I have an example here:
http://www.anecka.com/google_dfp/
As you can see, initial page load and refresh works fine, when the user switches between tabs the Google DFP ads disappear. Google Console shows my tagging is correct, and no javascript errors in the console.
I've got a method that pushes the ads:
function pushVerticalGoogleAd(slot, div_id) {
googletag.cmd.push(function() {
googletag.defineSlot('/7085388/' + slot, [950, 80], div_id).addService(googletag.pubads());
googletag.enableServices();
googletag.display(div_id);
});
}
Each tab contains a call to this method like so:
pushVerticalGoogleAd('homepage_top_950x80', 'ad1');
Now before you say that it's because I'm reusing the same div-id and I'm declaring duplicate slots, well I agree but whenever I randomize the ad div_ids on the server, it's still presenting this problem.
I know I'm probably pounding a nail with a shoe here, so anybody with Google DFP experience know where I can get a hammer? :)
Thanks
I think you should try using the refresh method... without knowing exactly what you are trying to do its hard to know if this will work for you but the below code does at least allow the ads to display with multiple clicks...
Try this:
<html>
<head>
<title>Test</title>
<link rel="stylesheet" href="css/ui-lightness/jquery-ui-1.8.24.custom.css" />
<script type="text/javascript" src="js/jquery-1.7.1.js"></script>
<script type="text/javascript" src="js/jquery.ui.core.js"></script>
<script type="text/javascript" src="js/jquery.ui.widget.js"></script>
<script type="text/javascript" src="js/tabs.js"></script>
<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">
var divs = {};
function pushVerticalGoogleAd(slot, div_id) {
if(div_id in divs) {
googletag.cmd.push(function() {
googletag.pubads().refresh([divs[div_id]]);
});
} else {
googletag.cmd.push(function() {
divs[div_id] = googletag.defineSlot('/7085388/' + slot, [950, 80], div_id).addService(googletag.pubads());
googletag.enableServices();
googletag.display(div_id);
});
}
}
</script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
$('#tabs-contain').tabs();
});
</script>
<div id="tabs-contain">
<ul id="tabs">
<li><span>Tab 1</span></li>
<li><span>Tab 2</span></li>
</ul>
</div>
</body>
</html>
Related
I'm facing a little challenge here.
I'm trying to implement ads in my blazor server solution, and i cannot get it to work. So i've come up with a small MVC app where it works.
I must say that the blazor app is for a client i'm working for, and I don't know who supplies these adds. They send the code that i must implement for it to work.
Here is the stuff that they have asked me to implement in the head of the webpage
<script type="text/javascript">
var utag_data = {
}
</script>
<!-- Loading script asynchronously -->
<script type="text/javascript">
(function(a,b,c,d){
a='//partnerurl';
b=document;c='script';d=b.createElement(c);d.src=a;d.type='text/java'+c;d.async=true;
a=b.getElementsByTagName(c)[0];a.parentNode.insertBefore(d,a);
})();
</script>
<script async='async' src='https://macro.adnami.io/macro/spec/adsm.macro.someId.js'></script>
<script>
var adsmtag = adsmtag || {};
adsmtag.cmd = adsmtag.cmd || [];
</script>
<link rel="preconnect" href="https://cdn.cookielaw.org">
<link rel="preload" href="https://cdn.cookielaw.org/consent/tcf.stub.js" as="script"/>
<script src="https://cdn.cookielaw.org/consent/tcf.stub.js" type="text/javascript" charset="UTF-8"></script>
<link rel="preconnect" href="https://securepubads.g.doubleclick.net">
<script async src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"></script>
<script>
var googletag = window.googletag || {};
googletag.cmd = googletag.cmd || [];
window.yb_configuration = {"domain":"clientdomain"};
(function (y, i, e, l, d, b, I, R, D) {
d.Yieldbird = d.Yieldbird || {};
d.Yieldbird.cmd = d.Yieldbird.cmd || [];
l.cmd.push(function () {l.pubads().disableInitialLoad();});
b = i.createElement('script'); b.async = true;
b.src = (e === 'https:' ? 'https:' : 'http:') + '//jscdn.yieldbird.com/' + y + '/yb.js';
I = i.getElementsByTagName('script')[0];
(I.parentNode || i.head).insertBefore(b, I);
})('950dff97-bb8d-4667-952b-d72ce8bbe88b', document, document.location.protocol, googletag, window);
</script>
<script>
googletag.cmd.push(function () {
googletag.pubads().enableLazyLoad({
fetchMarginPercent: 150,
renderMarginPercent: 75,
mobileScaling: 1.5
});
});
</script>
And for each add placement i've received some html/javascript i must place at the location.
Heres an example:
<!-- /x,y/domain/domain.dk/billboard_1 -->
<script async="async" src="https://securepubads.g.doubleclick.net/tag/js/gpt.js">
</script>
<script>
var googletag = googletag || {};googletag.cmd = googletag.cmd || [];
</script>
<script>
googletag.cmd.push(
function() {
var YBmapping = googletag.sizeMapping().addSize([931,0],[[930,180]]).addSize([0,0],[]).build();
googletag.defineSlot('/x,y/domain/domain.dk/billboard_1', [[930, 180]], 'div-gpt-ad-billboard_1').defineSizeMapping(YBmapping).addService(googletag.pubads());
googletag.enableServices();
});
</script>
<div id='div-gpt-ad-billboard_1'>
<script>
googletag.cmd.push(function() {
googletag.display('div-gpt-ad-billboard_1');});
</script>
</div>
I've obfuscted some variables. But i guess you get the hang of it..
This is from the MVC app, and it works. It places extra html inside my div with the div-gpt-ad-billboard_1 id. So on the website the HTML would look like this:
<div id="div-gpt-ad-billboard_1">
<script>
googletag.cmd.push(function() {
googletag.display('div-gpt-ad-billboard_1');});
</script>
<div id="google_ads_iframe_/x,y/domain/domain.dk/billboard_1_0__container__" style="border: 0pt none; width: 930px; height: 0px;"></div></div>
And if i deploy my MVC app to the live endpoint we have, an iFrame is inserted into the div with the google_ads_iframe Id, where the add is displayed.
Now on my blazor app, this doesn't happen.
I've created a blazor component which contains the ad i want to place. It looks like this:
<script async="async" suppress-error="BL9992" src="https://securepubads.g.doubleclick.net/tag/js/gpt.js">
</script>
<script suppress-error="BL9992">
var googletag = googletag || {};googletag.cmd = googletag.cmd || [];
</script>
<script suppress-error="BL9992">
googletag.cmd.push(
function() {
var YBmapping = googletag.sizeMapping().addSize([931,0],[[930,180]]).addSize([0,0],[]).build();
googletag.defineSlot('x,y/domain/domain.dk/billboard_1', [[930, 180]], 'div-gpt-ad-billboard_1').defineSizeMapping(YBmapping).addService(googletag.pubads());
googletag.enableServices();
console.log(googletag);
});
</script>
<div id='div-gpt-ad-billboard_1'>
<script suppress-error="BL9992">
googletag.cmd.push(function() {
googletag.display('div-gpt-ad-billboard_1');});
</script>
</div>
As i understand it you cannot directly call script tags in blazor components, but they work if you add the suppress-error, and i can atleast get it to console log from them.
The head is the same in the blazor app as in the MVC app, as script tag works fine in _Host.cshtml in blazor.
The issue is that for my blazor app the ad component looks like this on the live endpoint:
<div id="div-gpt-ad-billboard_1"><script><!--!-->
googletag.cmd.push(function() { googletag.display('div-gpt-ad-billboard_1');});
</script></div>
Notice that the entire div with the google iframe ID is missing. It's as if it doesn't update anything. I've tried to call statehaschanged from OnInitializedAsync. Nothing happens, and i guess it makes sense, since nothing is probably added to the render tree that statehaschanged activates the rerendering of.
Does anyone have any idea, how i can get it to work like the MVC app ?
I like to add Media.Net Network via JavaScript to MoPub. The team from Media.Net send me javascript I shoudl add to MoPub Network tab. So far so good.
They send me exactly this code:
//Add this code in head section
<script type="text/javascript">
window._mNHandle = window._mNHandle || {};
window._mNHandle.queue = window._mNHandle.queue || [];
medianet_versionId = "3121199";
</script>
<script src="//contextual.media.net/dmedianet.js?cid=MYCUSTOMERKEY" async="async"></script>
//Add this code in body section
<div id="BANNERKEY">
<script type="text/javascript">
try {
window._mNHandle.queue.push(function () {
window._mNDetails.loadTag("BANNERKEY", "320x50", "BANNERKEY");
});
}
catch (error) {
}
</script>
</div>
I believe both tags should go to the network tab of MoPub like this:
But here comes the question. MoPub highly recommends to add a failover tag in case the network responds with a no fill or any other error. But my knowledge is limited to add this failover tag to the Media.Net javascript code.
<script type="text/javascript" charset="utf-8"> loaded=true; window.location="mopub://failLoad"; </script>
I added the failover tag to the catch block and it seems to work.
<script type="text/javascript">
window._mNHandle = window._mNHandle || {};
window._mNHandle.queue = window._mNHandle.queue || [];
medianet_versionId = "3121199";
</script>
<script src="//contextual.media.net/dmedianet.js?cid=MYCUSTOMERKEY" async="async">
</script>
<div id="BANNERKEY">
<script type="text/javascript">
try {
window._mNHandle.queue.push(function () {
window._mNDetails.loadTag("BANNERKEY", "320x50", "BANNERKEY");
});
}
catch (error) {
loaded= true;
window.location="mopub://failLoad";
}
</script>
</div>
I'm trying to add a JustGiving widget to my website but it doesn't display at all. I had other scripts in the file which I thought might be interfering so I ended up testing in a new plain html file and it still wouldn't work.
Interestingly enough if I copy/paste it into a W3 schools code editor it works! It's the same exact code and I cannot work out why it doesn't load in an html file.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="jg-charity-events-board" data-config="id=45107">123</div>
<script>
(function(d) {
var jg = d.createElement('script');
jg.type = 'text/javascript';
jg.async = true;
jg.src = (d.location.protocol == 'https:' ? 'https://widgets.justgiving.com/charity-events-board/host.js' : 'http://widgets.justgiving.com/charity-events-board/host.js');
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(jg, s);
})(document);
</script>
</body>
</html>
Why do you just not use something like this? Didn't test but I assume it works.
<div id="scripts"></div>
<script>
var url = document.location.protocol + '//widgets.justgiving.com/charity-events-board/host.js';
var script = '<script type="text/javascript" src="${url}"></script>';
document.getElementById("scripts").innerHTML = script;
</script>
And jQuery has html and append functions for this.
I am trying to first create an iframe and then inject into it jQuery library and then have an alert to say that jQuery has loaded.
The jQuery library is being inserted into the iframe head as expected and the alert on jQuery load into the body.
The problem is, it does not show the alert and instead says jQuery is not defined.
Can anyone suggest anything?
Here is the code
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<title>iFrame Test</title>
</head>
<body>
<script>
var insertScript = function(src){
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = false;
script.src = src;
$('iframe').contents().find('head')[0].appendChild(script);
}
var insertScriptContent = function(code){
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = false;
script.innerHTML = code;
$('iframe').contents().find('body')[0].appendChild(script);
}
$(function(){
$('iframe').load(function(){
var contents = $('iframe').contents();
insertScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js');
insertScriptContent('jQuery(function(){ alert("loaded"); });');
});
});
</script>
<div class="output">
<iframe></iframe>
</div>
</body>
</html>
You're loading jQuery asynchronously (despite the script.async=false) and then loading your alert script immediately after that. jQuery is not yet loaded when that script runs, so you get the undefined jQuery reference.
As a quick fix, I added a setInterval() that waits until jQuery is defined. I also made these other changes:
Removed the script.async = false; both places because it doesn't do any good.
Removed the $('iframe').load() wrapper. When I tested your code, the callback function in that wrapper never gets called at all. That's not surprising since nothing is being loaded into the iframe at that point.
Changed the two places where you use document.createElement() to use the iframe document (called iframedoc in my version) instead. It works OK using document, but I'm a bit more comfortable creating those scripts under the document they will be loaded into.
Changed two instances of ...find(something)[0].appendChild(); to the simpler ...find(something).append();.
Here's the working code:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript">
</script>
<title>iFrame Test</title>
</head>
<body>
<script type="text/javascript">
$(function() {
var $contents = $('iframe').contents();
var iframedoc = $contents[0];
var insertScript = function(src) {
var script = iframedoc.createElement('script');
script.type = 'text/javascript';
script.src = src;
$('iframe').contents().find('head').append(script);
}
var insertScriptContent = function(code) {
var script = iframedoc.createElement('script');
script.type = 'text/javascript';
script.innerHTML = code;
$('iframe').contents().find('body').append(script);
}
insertScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js');
insertScriptContent(
'var timer = setInterval( function() {' +
'if( typeof jQuery == "undefined" ) return;' +
'clearInterval( timer );' +
'jQuery(function(){ alert("loaded"); });' +
'}, 50 )'
);
});
</script>
<div class="output">
<iframe></iframe>
</div>
</body>
</html>
That was good for a first pass, but there's a simpler way to do it. I tried replacing the two script functions with jQuery code, so here is another working version:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript">
</script>
<title>iFrame Test</title>
</head>
<body>
<script type="text/javascript">
$(function() {
var $contents = $('iframe').contents();
$contents.find('head').append(
'<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"><\/script>'
);
$contents.find('body').append(
'<script>' +
'jQuery(function(){ alert("loaded"); });' +
'<\/script>'
);
});
</script>
<div class="output">
<iframe></iframe>
</div>
</body>
</html>
Oddly enough, this one works OK without the setInterval() timer, so I took that code out. I'm not sure exactly why this works - which is not a comforting feeling - but it does seem to be consistent in the browsers I tested it in.
And finally, here is a non-working experiment. In the past I've used document.write() targeting an iframe to good effect. So I thought I would try that:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript">
</script>
<title>iFrame Test</title>
</head>
<body>
<script type="text/javascript">
$(function() {
var $contents = $('iframe').contents();
var iframedoc = $contents[0];
iframedoc.write(
'<!doctype html>',
'<html>',
'<head>',
'<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.js"><\/script>',
'</head>',
'<body>',
'<script>',
'debugger;',
'jQuery( function(){ alert("loaded"); } );',
'<\/script>',
'</body>',
'</html>'
);
});
</script>
<div class="output">
<iframe></iframe>
</div>
</body>
</html>
This version does load jQuery and the inline script into the iframe, and it executes the jQuery() call in the inline script. But it never calls the callback function with the alert() in it. This actually relates to something I'm working on, so I'll probably take another look at it tomorrow, but in the meantime I left the experimental code in case you're curious. I changed it to use the uncompressed jQuery inside the iframe for easy debugging, and left a debugger; statement in there.
I'm trying to convert a project to use requirejs instead of the solution I have below. Currently I have a layout page that contains all of the scripts at the bottom of the page (except modernizr) before the tag like this:
<head>
<script src="#Links.Assets.Scripts.Libraries.modernizr_2_6_2_js"></script>
</head>
<body>
<!-- Page content goes here -->
#RenderSection("PreScripts", false)
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="#Links.Assets.Scripts.Libraries.jquery_1_9_1_min_js"><\/script>')</script>
<script src="#Links.Assets.Scripts.Libraries.jquery_namespace_js"></script>
<script src="#Links.Assets.Scripts.Libraries.jquery_unobtrusive_ajax_js"></script>
<script src="#Links.Assets.Scripts.Libraries.jquery_validate_js"></script>
<script src="#Links.Assets.Scripts.Libraries.jquery_validate_unobtrusive_js"></script>
<script src="#Links.Assets.Scripts.Libraries.jquery_timeago_js"></script>
<script src="#Links.Assets.Scripts.Libraries.toastr_js"></script>
<script src="#Links.Assets.Scripts.Views.Shared._master_js"></script>
#RenderSection("PostScripts", false)
#{
var errorMessage = TempData[TempDataConstants.ErrorMessage] as string;
var infoMessage = TempData[TempDataConstants.InfoMessage] as string;
var successMessage = TempData[TempDataConstants.SuccessMessage] as string;
if (!string.IsNullOrEmpty(errorMessage)) {
<script>
var origTimeOut = toastr.options.timeOut;
toastr.options.timeOut = 0;
toastr.error(#Html.Raw(Json.Encode(errorMessage)));
toastr.options.timeOut = origTimeOut;
</script>
}
if (!string.IsNullOrEmpty(successMessage)) {
<script>
var origTimeOut = toastr.options.timeOut;
toastr.options.timeOut = 0;
toastr.success(#Html.Raw(Json.Encode(successMessage)));
toastr.options.timeOut = origTimeOut;
</script>
}
if (!string.IsNullOrEmpty(infoMessage)) {
<script>
var origTimeOut = toastr.options.timeOut;
toastr.options.timeOut = 0;
toastr.info(#Html.Raw(Json.Encode(infoMessage)));
toastr.options.timeOut = origTimeOut;
</script>
}
}
</body>
In the individual pages that use this layout page I then populate the PostScripts section:
#section PostScripts {
// Javascript that belongs to a single page goes here.
}
Problems
I've followed this example but as you can see where I'm checking TempData on the server to see if its not null to popup a toastr message on the client. I"m not really sure the best way to go about doing this and have tried many things. Any ideas?