簡體   English   中英

Google DFP-從內部調整SafeFrame自定義廣告素材外部iframe容器的尺寸(展開廣告)

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

我正在尋找可以從Google DFP廣告管理系統中的自定義廣告素材內部擴展SafeFrame自定義廣告的解決方案,這是否有可能?

有兩種可能的解決方案:

1)使用SafeFrame API

優點:

  • 您可以“開箱即用”使用它
  • 您可以在任何網站上使用它,不需要網站上的自定義代碼
  • 使用安全

缺點:

  • 僅限於填充網站的可見區域
  • 需要等待,直到用戶看到廣告單元

2)使用window.postMessage() javascript方法編寫自己的API

缺點:

  • 您需要向您的網站添加自定義代碼
  • 如果您使用一些第三方廣告素材,則可能會構成威脅

優點:

  • 您可以使用廣告素材對網站進行幾乎任何操作

1)使用SafeFrame API

該API實際上非常易於使用,您可以在GPT Safeframe預覽工具中查看一些示例。

首先,您需要在網站的<head>中更新DFP初始化腳本

var pageConfig = {
    allowOverlayExpansion: true,
    allowPushExpansion: true,
    sandbox: true
};
googletag.pubads().setSafeFrameConfig(pageConfig);

這將允許在您的網站上展開SafeFrame廣告。 有關通過GPT控制SafeFrame容器行為的更多信息。

現在,您可以創建自定義廣告素材並將其作為SafeFrame投放到您的網站上。 這是我的一個例子。 此示例可以“等待”直到可見,然后將其擴展到SafeFrame內部的<div id="container">高度:

<div id="container">
    some lines to 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 any
    var expanded = false;
    function expand() {
        var self= $sf.ext.geom().self;
        var config = {
            push: true, // we want to push expanded content
            b: 0
        };

        var el = document.getElementById('container');
        var containerHeight = el.offsetHeight;

        // get height from bottom, that need to be expanded
        var expandBottom = containerHeight - self.h;

        // if container is whole inside a SafeFrame, it will not expand
        if(expandBottom < 0) return;

        config.b = expandBottom;
        $sf.ext.expand(config);
    }

    function expandDelayed(forceExpand) {
        // expand will run just once, or you can force it to run again
        // but collapse first is needed
        if(expanded && forceExpand || !expanded) {
            $sf.ext.collapse();
            expanded = false;
            // there must be some timeout, because .collapse(); method is deplayed somehow
            setTimeout(expand, 0);
        }
    }

    $sf.ext.register(160, 150, function(status, data) {
        // this code will do whole magic of "waiting" for right moment
        if (status === 'geom-update') {
            expandDelayed();
        }

        // change global expanded status
        if (status === 'expanded') {
            expanded = true;
        }
    });

    // init
    expandDelayed();
</script>

2.使用window.postMessage() javascript方法編寫自己的API

首先,您需要將此代碼放入網站<head>的DFP初始化腳本中。 此代碼會將廣告位的ID作為#hash-tag<iframe>的src中,以便您可以從廣告素材中獲取它。

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 by 10 milliseconds, because iframe is not yet fully rendered
    // and limited to max to 10 seconds to wait 
    var timeoutFunction = function () {
        var src = "#" + containerId;
        // `src` attribute is null, when iframe is FriendlyIframe, and
        // when it's present, then 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);
});

其次,您需要將此代碼添加到您的網站中,最好將其添加為單獨的.js文件。

function onMessageReceivedGetStyle(e) {

    // this will filter just setStyle commands from 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 from id, we don't use jquery
    var elementId = e.data.id.replace(/#/, "");

    var wrapperEl = document.getElementById(elementId);
    if (wrapperEl === null) {
        return;
    }

    var elements = [wrapperEl];
    // you can target child elements too with 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;
    }
}

第三件事是您在DFP廣告管理系統中使用自定義類型的廣告素材的自定義代碼。 這是示例,與第一個示例類似,但是在此腳本可以等待,直到所有內容和圖像都加載完畢,然后再使用廣告素材擴展/縮小iframe:

<div id="container">
    <a href="#" target="_blank">
        <img src="%%FILE:JPG1%%">
    </a>
    <a href="#" target="_blank">
        <img src="%%FILE:JPG2%%">
    </a>
</div>

<style>
    a {
        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;
        }

        // get ID of your Ad unit <div> with this 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 with to fullwidth, and height to height of container inside creative
        var width = '100%';
        var height = container.offsetHeight + 'px';

        // send our request to website
        window.top.postMessage({
            cmd: 'setStyle',
            id: divGptAdId,
            query: 'div, iframe', // we want to target child div and iframe and don't change container styles
            params: {
                display: 'block',
                height: height,
                width: width
            }
        }, '*');
    }

    document.onreadystatechange = function () {
        // resize iframe when all is loaded
        if (document.readyState == "complete") {
            resizeOutsideSafeFrame();
        }
    };

    // first resize must occur little bit later 
    setTimeout(resizeOutsideSafeFrame, 100);
</script>

就這樣。 如果您想從iframe內部更改網站上的任何內容,則可以在網站上編寫自己的cmd,然后從iframe內部調用此命令。


編輯1:現在才注意到, var divGptAdId = '%%PATTERN:url%%; 不會以#hash方式在頁面上返回正確的div ID,因此現在需要為他提供正確的容器div ID更改:

if(!divGptAdId) {
    return;
}

if(!divGptAdId) { 
    divGptAdId = 'div-gpt-ad-container-div-id-1';
}

我找不到任何可靠的文檔,因此PayteR的示例極大地幫助了我! 我必須嘗試新的維度,才能使廣告以正確的方式進行擴展。

這是我從PayteR的示例創建的一些示例代碼:

/* Main object for namespacing */
var Ad = function(obj) {};

/* 
  Register your ad with the dimensions of the current ad.
  - This is basically an event handler for the the ad frame.
  - 728 initial ad width
  - 90 initial ad height
*/
Ad.prototype.registerExpand = function() {
  $sf.ext.register(728, 90, function(status, data){});
};

/* Expand function to be called on click or load */
Ad.prototype.expandAd = function() {

  /* Get the current geometry of your ad */
  var self = $sf.ext.geom().self;

  /* 
    Set the new geometry
    - Increase height 315 pixels
    - Expand downward by setting the bottom to the new height minus the current height
  */
  $sf.ext.expand({
    h: 315,
    b: 315 - self.h
  });
};


/* Intialize, register, and expand */
var ad = new Ad();
ad.registerExpand();
ad.expandAd();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM