Google DFP广告管理系统 - 从内部调整SafeFrame自定义广告素材外部iframe容器(展开广告) [英] Google DFP - Resize SafeFrame custom creative outer Iframe container from inside (expand ad)
问题描述
我正在搜索可以在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屋!