Google DFP广告管理系统 - 从内部调整SafeFrame自定义广告素材外部iframe容器(展开广告) [英] Google DFP - Resize SafeFrame custom creative outer Iframe container from inside (expand ad)

查看:302
本文介绍了Google DFP广告管理系统 - 从内部调整SafeFrame自定义广告素材外部iframe容器(展开广告)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在搜索可以在Google DFP广告管理系统中自定义广告素材内展开SafeFrame自定义广告的解决方案,这有可能吗?

i'm searching for solution, that can expand SafeFrame custom ad from inside of custom creative in Google DFP, is that possible somehow?

推荐答案

有两种可能的解决方案:

There are 2 possible solutions:

1)使用 SafeFrame API

1) using SafeFrame API

专业人士:


  • 你可以开箱即用使用它

  • 您可以在任何网站上使用它,网站上不需要自定义代码

  • 可以安全使用

缺点:


  • 仅限于填写网站的可见区域

  • 需要等待,直到广告单元对用户可见

2)代码你的自己的API window.postMessage() javascript方法

2) code your own API with window.postMessage() javascript method

缺点:


  • 您需要向您的网站添加自定义代码

  • 如果您使用某些第三方广告,则可能存在威胁

专业人士:


  • 您可以通过广告素材为您的网站做几乎所有事情

此API使用起来很容易,您可以在
GPT Safeframe预览工具中看到一些示例

This API is realatively easy to use, you can see some examples in GPT Safeframe preview tool.

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

First you need to update your DFP initialization script in <head> of your website

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

这样可以在您的网站上展开SafeFrame广告。有关详细信息,请参阅
通过GPT控制SafeFrame容器行为

This will allow to expand SafeFrame ads on your website. More about this in Control SafeFrame Container behavior through GPT.

现在,您可以创建自定义广告素材并在网站上将其作为SafeFrame投放。这是我的一个例子。这个例子可以等待它的可见性,然后将扩展到SafeFrame中的< div id =container> 的高度:

Now you can create custom creative and serve it as SafeFrame on your website. Here is my one example. This Example can "wait" util it's visible, and then will expand to height of <div id="container"> that is inside of SafeFrame:

<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初始化脚本。此代码会将 #hash-tag 的广告位ID添加到< iframe> 的src中,这样您就可以了可以从广告素材中获取。

2. code your own API with window.postMessage() javascript method

First, you need to put this code, to your DFP initialization script in <head> of your website. This code will add an ID of Ad slot as #hash-tag to <iframe>'s src so you can get it from inside of your 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 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文件。

Second, you need to add this code to your website, better as separated .js file.

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中的广告素材。这是一个示例,类似于
第一个示例中的示例,但此处此脚本可以等到加载所有内容和图像,然后使用creative扩展/缩小
iframe:

And third thing is your custom code in custom type of creative in DFP. Here is example, that is similar to that in first example, but here this script can wait until all content and image is loaded and then will expand/shrink your iframe with creative:

<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内部调用此命令。

That's all. When you want to change anything on your website from inside of iframe, you can code your own cmd on your website and call this command from inside of the iframe.

编辑1:
现在才注意到, var divGptAdId ='%% PATTERN:url %%; 不会以#hash方式在页面上返回div的正确ID,所以现在需要给他一个正确的容器div id更改:

Edit 1: just noticed now, that var divGptAdId = '%%PATTERN:url%%; will not return correct id of div on the page in #hash way, so now it's needed to give him a correct container div id change:

if(!divGptAdId) {
    return;
}

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

这篇关于Google DFP广告管理系统 - 从内部调整SafeFrame自定义广告素材外部iframe容器(展开广告)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆