javascript - Google DFP - Resize SafeFrame custom creative outer Iframe container from inside (expand ad) -


i'm searching solution, can expand safeframe custom ad inside of custom creative in google dfp, possible somehow?

there 2 possible solutions:

1) using safeframe api

pros:

  • u can use "out of box"
  • you can use on website, no custom code on website needed
  • it's safe use

cons:

  • it's limited fill visible area of website
  • need wait, until ad unit visible user

2) code own api window.postmessage() javascript method

cons:

  • you need add custom code website
  • it's possible threat, if use 3th party creatives

pros:

  • you can website creative

1) using safeframe api

this api realatively easy use, can see examples in gpt safeframe preview tool.

first need update dfp initialization script in <head> of website

var pageconfig = {     allowoverlayexpansion: true,     allowpushexpansion: true,     sandbox: true }; googletag.pubads().setsafeframeconfig(pageconfig); 

this allow expand safeframe ads on website. more in control safeframe container behavior through gpt.

now can create custom creative , serve safeframe on website. here 1 example. example can "wait" util it's visible, , expand height of <div id="container"> inside of safeframe:

<div id="container">     lines make container height<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br>     line<br> </div>  <script>     // global expanded indicator variable, because api don't have     var expanded = false;     function expand() {         var self= $sf.ext.geom().self;         var config = {             push: true, // want push expanded content             b: 0         };          var el = document.getelementbyid('container');         var containerheight = el.offsetheight;          // height bottom, need expanded         var expandbottom = containerheight - self.h;          // if container whole inside safeframe, not expand         if(expandbottom < 0) return;          config.b = expandbottom;         $sf.ext.expand(config);     }      function expanddelayed(forceexpand) {         // expand run once, or can force run again         // collapse first needed         if(expanded && forceexpand || !expanded) {             $sf.ext.collapse();             expanded = false;             // there must timeout, because .collapse(); method deplayed somehow             settimeout(expand, 0);         }     }      $sf.ext.register(160, 150, function(status, data) {         // code whole magic of "waiting" right moment         if (status === 'geom-update') {             expanddelayed();         }          // change global expanded status         if (status === 'expanded') {             expanded = true;         }     });      // init     expanddelayed(); </script> 

2. code own api window.postmessage() javascript method

first, need put code, dfp initialization script in <head> of website. code add id of ad slot #hash-tag <iframe>'s src can inside of creative.

googletag.pubads().addeventlistener('slotrenderended', function (event) {     var containerid = event.slot.getslotelementid();     var containerel = document.getelementbyid(containerid);      if (containerel === null) return;      var iframeel = containerel.queryselectorall('iframe')[0];      // it's delayed 10 milliseconds, because iframe not yet rendered     // , limited max 10 seconds wait      var timeoutfunction = function () {         var src = "#" + containerid;         // `src` attribute null, when iframe friendlyiframe, ,         // when it's present, it's safeframe         if (iframeel.getattribute('src') !== null) {             src = iframeel.getattribute('src').replace(/#.*/, "") + src;         } else {             var name = iframeel.getattribute('name') + "#" + containerid;             iframeel.setattribute('name', name);         }         iframeel.setattribute('src', src);     };     settimeout(timeoutfunction, 10); }); 

second, need add code website, better separated .js file.

function onmessagereceivedgetstyle(e) {      // filter setstyle commands correct origin     if (         !(e.origin === 'http://tpc.googlesyndication.com' || e.origin === 'https://tpc.googlesyndication.com') ||         typeof e.data !== 'object' ||         typeof e.data.id !== 'string' ||         e.data.cmd !== 'setstyle' ||         typeof e.data.params !== 'object'     ) {         return;     }      // remove # character id, don't use jquery     var elementid = e.data.id.replace(/#/, "");      var wrapperel = document.getelementbyid(elementid);     if (wrapperel === null) {         return;     }      var elements = [wrapperel];     // can target child elements query parameter     if (typeof e.data.query === 'string' && e.data.query) {         elements = wrapperel.queryselectorall(e.data.query);     }      elements.foreach(function (element) {         object.keys(e.data.params).foreach(function (param) {             element.style[param] = e.data.params[param];         });     });  }  if (window.addeventlistener) {     addeventlistener('message', onmessagereceivedgetstyle, false); } else {     if (window.attachevent) {         attachevent('onmessage', onmessagereceivedgetstyle);     }     else {         window.onmessage = onmessagereceivedgetstyle;     } } 

and third thing custom code in custom type of creative in dfp. here example, similar in first example, here script can wait until content , image loaded , expand/shrink iframe creative:

<div id="container">     <a href="#" target="_blank">         <img src="%%file:jpg1%%">     </a>     <a href="#" target="_blank">         <img src="%%file:jpg2%%">     </a> </div>  <style>     {         display: block;         margin-bottom: .5em;     }     img {         display: block;         max-width: 100%;     }     *:last-child {         margin-bottom: 0;     } </style>  <script>     var container = document.getelementbyid('container');      function resizeoutsidesafeframe() {         if (!window.top.postmessage) {             return false;         }          // id of ad unit <div> creative          var divgptadid = '%%pattern:url%%';          if (divgptadid.indexof('#') !== -1) {             divgptadid = divgptadid.split('#')[1];         } else {             divgptadid = window.location.hash;         }          if(!divgptadid) {                         if (window.name.indexof('#') !== -1) {                                divgptadid = window.name.split('#')[1];             }         }          if(!divgptadid) {             return;         }          // set fullwidth, , height height of container inside creative         var width = '100%';         var height = container.offsetheight + 'px';          // send our request website         window.top.postmessage({             cmd: 'setstyle',             id: divgptadid,             query: 'div, iframe', // want target child div , iframe , don't change container styles             params: {                 display: 'block',                 height: height,                 width: width             }         }, '*');     }      document.onreadystatechange = function () {         // resize iframe when loaded         if (document.readystate == "complete") {             resizeoutsidesafeframe();         }     };      // first resize must occur little bit later      settimeout(resizeoutsidesafeframe, 100); </script> 

that's all. when want change on website inside of iframe, can code own cmd on website , call command inside of iframe.


Comments

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -