如何在ajax成功时重新加载DFP广告?

时间:2015-10-13 16:25:25

标签: jquery ajax google-dfp

背景故事: 每次完成新的搜索结果时,服务器都会返回整页HTML。这包括广告(具有新的定位,ID等)。

我需要重新加载DFP广告管理系统中的一个广告,该广告位于搜索结果包装器内(内容通过AJAX更新)。这是我目前的代码:



'use strict';
var $ = require('jquery');
require('./dfp-events');
var advertisements = {};
module.exports = advertisements;

// component configuration
var COMPONENT_ATTR = 'data-advertisement';
var COMPONENT_SELECTOR = '[' + COMPONENT_ATTR + ']';
var LAZY_INIT_SELECTOR = '[data-advertisement-init="lazy"]';

var SIZE_MAPPING_ATTR = 'data-advertisement-size-mapping';
var SIZE_DEFAULT_ATTR = 'data-advertisement-size-default';
var ADUNIT_PATH_ATTR = 'data-advertisement-adunit-path';
var CATEGORIES_URL_ATTR = 'data-advertisement-categories-url';
var GOOGLE_TAG_SERVICE_URL = 'https://www.googletagservices.com/tag/js/gpt.js';
var USER_ACCEPTED_COOKIES_ATTR = 'data-advertisement-has-user-accepted-cookies';
var REFRESH_AD_ATTR = 'data-advertisement-refresh';

advertisements.create = function(elements) {
    var component = this;
    advertisements.loadGoogleTagServices();
    window.googletag.cmd.push(function() {
        window.googletag.pubads().setCookieOptions(advertisements.getCookieOptions(elements));
        window.googletag.pubads().collapseEmptyDivs(true);
        window.googletag.enableServices();

        [].forEach.call(elements, function(element) {
            var config = advertisements.getAdConfig(element);
            advertisements.instances.push(element);
            element.id = config.id;
            advertisements.addSlot(config);
            advertisements.refreshAdAfterScroll(element);
            advertisements.refreshAdAfterResultsUpdated();
        });


        window.googletag.enableServices();
        window.googletag.cmd.push(function() {
            window.googletag.on('gpt-slot_rendered', function(e,level,message,service,slot) {
                var slotId = slot.getSlotId();
                var $slot = $('#' + slotId.getDomId());

                // DFP adds two iframes, one for calling scripts and one for displaying the ad. we want the one that is not hidden
                if ($slot.find('iframe:not([id*=hidden])')
                    .map(function() { return this.contentWindow.document; })
                    .find('body')
                    .children().length > 0
                ) {
                    $slot.find('iframe').contents().find('body').addClass('redesign');
                }
            });
        });
    });

    component.bindEvents();
};

advertisements.bindEvents = function() {
    // THIS IS TRIGGERED AFTER THE SEARCH RESULTS ARE DONE
    $(document).on('resultsUpdated', function(elements) {
        console.log('gottgis');
        // HERE IS WHERE I'D LIKE TO GET NEW DATA_ATTRIBUTES AND RELOAD THE DFP.
    });
};

advertisements.refreshAdAfterScroll = function(element) {
    var refreshAttr = (element.getAttribute(REFRESH_AD_ATTR).toLowerCase());
    var maxAdHeight = 650;
    var atEnd = false;
    var point2 = (($('[' + REFRESH_AD_ATTR + ']').offset().top) + maxAdHeight);
    var lastScrollTop = 0;
    var scrolledToPosition = false;

    if (refreshAttr !== 'true') {
        return;
    }

    $(window).scroll(function() {
        var currentTopPosition = $(this).scrollTop();

        if ($(window).scrollTop() + $(window).height() > $(document).height() - maxAdHeight) {
            atEnd = true;
        }

        if (currentTopPosition < lastScrollTop && currentTopPosition < point2 && atEnd) {
            if (!scrolledToPosition) {
                window.googletag.pubads().refresh();
                scrolledToPosition = true;
            }
        }
        lastScrollTop = currentTopPosition;
    });
};

advertisements.instances = [];
advertisements.cachedCategoriesByUrl = {};

advertisements.getCategories = function(categoriesUrl) {
    var cachedCategories = advertisements.cachedCategoriesByUrl[categoriesUrl];
    if (cachedCategories) {
        return cachedCategories;
    } else {
        var getCategories = $.ajax(categoriesUrl);
        advertisements.cachedCategoriesByUrl[categoriesUrl] = getCategories;
        return getCategories;
    }
};

advertisements.getCookieOptions = function(elements) {
    var cookiesAccepted = elements[0].getAttribute(USER_ACCEPTED_COOKIES_ATTR);
    //Get the first element,this attribute has to be the same for all the ads
    if (cookiesAccepted && cookiesAccepted.toLowerCase() === 'true') {
        return 0;
    }
    return 1;
};

advertisements.getAdConfig = function(element) {
    return {
        id: element.id || 'ad-' + advertisements.instances.length,
        adunitpath: element.getAttribute(ADUNIT_PATH_ATTR),
        sizemapping: JSON.parse(element.getAttribute(SIZE_MAPPING_ATTR)),
        sizedefault: JSON.parse(element.getAttribute(SIZE_DEFAULT_ATTR)),
        categoriesUrl: element.getAttribute(CATEGORIES_URL_ATTR)
    };
};

advertisements.addSlot = function(ad) {
    advertisements.getCategories(ad.categoriesUrl)
        .catch(function() {
            return {};
        })
        .then(function(categories) {
            advertisements.advertisementSlot(ad, categories);
        });
};

advertisements.advertisementSlot = function(ad, categories) {
    var tag = window.googletag
        .defineSlot(ad.adunitpath, ad.sizedefault, ad.id)
        .defineSizeMapping(ad.sizemapping)
        .addService(window.googletag.pubads());

    for (var key in categories) {
        if (categories.hasOwnProperty(key)) {
            tag.setTargeting(key, categories[key]);
        }
    }

    window.googletag.display(ad.id);
};

advertisements.loadGoogleTagServices = function() {
    window.googletag = window.googletag || {};
    window.googletag.cmd = window.googletag.cmd || [];

    var gads = document.createElement('script');
    gads.async = true;
    gads.src = GOOGLE_TAG_SERVICE_URL;
    var node = document.getElementsByTagName('script')[0];
    node.parentNode.insertBefore(gads, node);
};

// Turn all elements with the default selector into components.
// Only one instance of advertisements per page.
advertisements.create(
    document.querySelectorAll(COMPONENT_SELECTOR + ':not(' + LAZY_INIT_SELECTOR + ')')
);
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

我知道这是一个老问题,但没有答案。以下是我在时间轴上通过JS刷新所有广告的示例。它正在使用新的DFP JS API。希望找到一个正在寻找的人。

var iInterval = 600000; // 10 Minutes
setInterval(function() {
    // Send DFP refresh request
    googletag.pubads().refresh();
}, iInterval);