无法在AngularJS视图中显示移动网络中的原生广告

时间:2016-09-12 21:05:13

标签: javascript html angularjs facebook-audience-network

在我的AngularJS应用程序中,我试图在我的一个视图中添加Facebook Native Web Ad。我按照in the documentation概述的步骤生成了必要的HTML代码段并将其添加到我的视图中。

我的应用程序正在使用ui-router来解析路由。访问包含此代码段的路径/视图时,不会显示FB广告,也不会调用任何回调(onAdLoaded或onAdError)。

Facebook生成的HTML代码段(已添加到视图中):

<div style="display:none; position: relative;">
    <iframe style="display:none;"></iframe>
    <script type="text/javascript">
        var data = {
            placementid: 'xxxxxxxxxxx_xxxxxxxx',
            format: 'native',
            testmode: true,
            onAdLoaded: function (element) {
                console.log('Audience Network ad loaded');
                element.style.display = 'block';
            },
            onAdError: function (errorCode, errorMessage) {
                console.log('Audience Network error (' + errorCode + ') ' + errorMessage);
            }
        };
        (function (w, l, d, t) {
            var a = t();
            var b = d.currentScript || (function () {
                        var c = d.getElementsByTagName('script');
                        return c[c.length - 1];
                    })();
            var e = b.parentElement;
            e.dataset.placementid = data.placementid;
            var f = function (v) {
                try {
                    return v.document.referrer;
                } catch (e) {
                }
                return '';
            };
            var g = function (h) {
                var i = h.indexOf('/', h.indexOf('://') + 3);
                if (i === -1) {
                    return h;
                }
                return h.substring(0, i);
            };
            var j = [l.href];
            var k = false;
            var m = false;
            if (w !== w.parent) {
                var n;
                var o = w;
                while (o !== n) {
                    var h;
                    try {
                        m = m || (o.$sf && o.$sf.ext);
                        h = o.location.href;
                    } catch (e) {
                        k = true;
                    }
                    j.push(h || f(n));
                    n = o;
                    o = o.parent;
                }
            }
            var p = l.ancestorOrigins;
            if (p) {
                if (p.length > 0) {
                    data.domain = p[p.length - 1];
                } else {
                    data.domain = g(j[j.length - 1]);
                }
            }
            data.url = j[j.length - 1];
            data.channel = g(j[0]);
            data.width = screen.width;
            data.height = screen.height;
            data.pixelratio = w.devicePixelRatio;
            data.placementindex = w.ADNW && w.ADNW.Ads ? w.ADNW.Ads.length : 0;
            data.crossdomain = k;
            data.safeframe = !!m;
            var q = {};
            q.iframe = e.firstElementChild;
            var r = 'https://www.facebook.com/audiencenetwork/web/?sdk=5.3';
            for (var s in data) {
                q[s] = data[s];
                if (typeof(data[s]) !== 'function') {
                    r += '&' + s + '=' + encodeURIComponent(data[s]);
                }
            }
            q.iframe.src = r;
            q.tagJsInitTime = a;
            q.rootElement = e;
            q.events = [];
            w.addEventListener('message', function (u) {
                if (u.source !== q.iframe.contentWindow) {
                    return;
                }
                u.data.receivedTimestamp = t();
                if (this.sdkEventHandler) {
                    this.sdkEventHandler(u.data);
                } else {
                    this.events.push(u.data);
                }
            }.bind(q), false);
            q.tagJsIframeAppendedTime = t();
            w.ADNW = w.ADNW || {};
            w.ADNW.Ads = w.ADNW.Ads || [];
            w.ADNW.Ads.push(q);
            w.ADNW.init && w.ADNW.init(q);
        })(window, location, document, Date.now || function () {
                    return +new Date;
                });
    </script>
    <script type="text/javascript" src="https://connect.facebook.net/en_US/fbadnw.js" async></script>
    <style>
        .thirdPartyRoot {
            background-color: white;
            color: #444;
            border: 1px solid #ccc;
            border-left: 0;
            border-right: 0;
            font-family: sans-serif;
            font-size: 14px;
            line-height: 16px;
            width: 320px;
            text-align: left;
            position: relative;
        }

        .thirdPartyMediaClass {
            width: 320px;
            height: 168px;
            margin: 12px 0;
        }

        .thirdPartySubtitleClass {
            font-size: 18px;
            -webkit-line-clamp: 1;
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            height: 16px;
            -webkit-box-orient: vertical;
        }

        .thirdPartyTitleClass {
            padding-right: 12px;
            line-height: 18px;
            -webkit-line-clamp: 2;
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            height: 36px;
            -webkit-box-orient: vertical;
        }

        .thirdPartyCallToActionClass {
            background-color: #416BC4;
            color: white;
            border-radius: 4px;
            padding: 6px 20px;
            float: right;
            text-align: center;
            text-transform: uppercase;
            font-size: 11px;
        }

        .fbDefaultNativeAdWrapper {
            font-size: 12px;
            line-height: 14px;
            margin: 12px 0;
            height: 36px;
            vertical-align: top;
        }
    </style>
    <div class="thirdPartyRoot">
        <a class="fbAdLink">
            <div class="fbAdMedia thirdPartyMediaClass"></div>
            <div class="fbAdSubtitle thirdPartySubtitleClass"></div>
            <div class="fbDefaultNativeAdWrapper">
                <div class="fbAdCallToAction thirdPartyCallToActionClass"></div>
                <div class="fbAdTitle thirdPartyTitleClass"></div>
            </div>
        </a>
    </div>
</div>

我注意到Facebook Audience Network JS是异步加载的,并且怀疑我可能会遇到导致问题的竞争条件。

<script type="text/javascript" src="https://connect.facebook.net/en_US/fbadnw.js" async></script>

为了测试这一点,我已将FB代码段移出我的视图并进入我的SPA index.html。广告按预期显示。加载脚本后, fbadnw.js 脚本会调用什么回调?是否在加载 fbadnw.js 之前调用FB生成的代码中的闭包?

index.html(有效)

    <!DOCTYPE html>
    <html ng-app="kcl-app">
    <head>
        <base href="/">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
        <title ng-bind="pageTitle"></title>
    </head>
    <body>

    <!-- ui-router view -->
    <div ui-view></div>

 <!-- FB Begin -->
    <div class="fb-native">
        <div style="display:none; position: relative;">
            <iframe style="display:none;"></iframe>
            <script type="text/javascript">
                var data = {
                    placementid: 'xxxxxxxxxxx_xxxxxxxx',
                    format: 'native',
                    testmode: true,
                    onAdLoaded: function (element) {
                        console.log('Audience Network ad loaded');
                        element.style.display = 'block';
                    },
                    onAdError: function (errorCode, errorMessage) {
                        console.log('Audience Network error (' + errorCode + ') ' + errorMessage);
                    }
                };
                (function (w, l, d, t) {
                    var a = t();
                    var b = d.currentScript || (function () {
                                var c = d.getElementsByTagName('script');
                                return c[c.length - 1];
                            })();
                    var e = b.parentElement;
                    e.dataset.placementid = data.placementid;
                    var f = function (v) {
                        try {
                            return v.document.referrer;
                        } catch (e) {
                        }
                        return '';
                    };
                    var g = function (h) {
                        var i = h.indexOf('/', h.indexOf('://') + 3);
                        if (i === -1) {
                            return h;
                        }
                        return h.substring(0, i);
                    };
                    var j = [l.href];
                    var k = false;
                    var m = false;
                    if (w !== w.parent) {
                        var n;
                        var o = w;
                        while (o !== n) {
                            var h;
                            try {
                                m = m || (o.$sf && o.$sf.ext);
                                h = o.location.href;
                            } catch (e) {
                                k = true;
                            }
                            j.push(h || f(n));
                            n = o;
                            o = o.parent;
                        }
                    }
                    var p = l.ancestorOrigins;
                    if (p) {
                        if (p.length > 0) {
                            data.domain = p[p.length - 1];
                        } else {
                            data.domain = g(j[j.length - 1]);
                        }
                    }
                    data.url = j[j.length - 1];
                    data.channel = g(j[0]);
                    data.width = screen.width;
                    data.height = screen.height;
                    data.pixelratio = w.devicePixelRatio;
                    data.placementindex = w.ADNW && w.ADNW.Ads ? w.ADNW.Ads.length : 0;
                    data.crossdomain = k;
                    data.safeframe = !!m;
                    var q = {};
                    q.iframe = e.firstElementChild;
                    var r = 'https://www.facebook.com/audiencenetwork/web/?sdk=5.3';
                    for (var s in data) {
                        q[s] = data[s];
                        if (typeof(data[s]) !== 'function') {
                            r += '&' + s + '=' + encodeURIComponent(data[s]);
                        }
                    }
                    q.iframe.src = r;
                    q.tagJsInitTime = a;
                    q.rootElement = e;
                    q.events = [];
                    w.addEventListener('message', function (u) {
                        if (u.source !== q.iframe.contentWindow) {
                            return;
                        }
                        u.data.receivedTimestamp = t();
                        if (this.sdkEventHandler) {
                            this.sdkEventHandler(u.data);
                        } else {
                            this.events.push(u.data);
                        }
                    }.bind(q), false);
                    q.tagJsIframeAppendedTime = t();
                    w.ADNW = w.ADNW || {};
                    w.ADNW.Ads = w.ADNW.Ads || [];
                    w.ADNW.Ads.push(q);
                    w.ADNW.init && w.ADNW.init(q);
                })(window, location, document, Date.now || function () {
                            return +new Date;
                        });
            </script>
            <script type="text/javascript" src="https://connect.facebook.net/en_US/fbadnw.js" async></script>
            <style>
                .thirdPartyRoot {
                    background-color: white;
                    color: #444;
                    border: 1px solid #ccc;
                    border-left: 0;
                    border-right: 0;
                    font-family: sans-serif;
                    font-size: 14px;
                    line-height: 16px;
                    width: 320px;
                    text-align: left;
                    position: relative;
                }

                .thirdPartyMediaClass {
                    width: 320px;
                    height: 168px;
                    margin: 12px 0;
                }

                .thirdPartySubtitleClass {
                    font-size: 18px;
                    -webkit-line-clamp: 1;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    display: -webkit-box;
                    height: 16px;
                    -webkit-box-orient: vertical;
                }

                .thirdPartyTitleClass {
                    padding-right: 12px;
                    line-height: 18px;
                    -webkit-line-clamp: 2;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    display: -webkit-box;
                    height: 36px;
                    -webkit-box-orient: vertical;
                }

                .thirdPartyCallToActionClass {
                    background-color: #416BC4;
                    color: white;
                    border-radius: 4px;
                    padding: 6px 20px;
                    float: right;
                    text-align: center;
                    text-transform: uppercase;
                    font-size: 11px;
                }

                .fbDefaultNativeAdWrapper {
                    font-size: 12px;
                    line-height: 14px;
                    margin: 12px 0;
                    height: 36px;
                    vertical-align: top;
                }
            </style>
            <div class="thirdPartyRoot">
                <a class="fbAdLink">
                    <div class="fbAdMedia thirdPartyMediaClass"></div>
                    <div class="fbAdSubtitle thirdPartySubtitleClass"></div>
                    <div class="fbDefaultNativeAdWrapper">
                        <div class="fbAdCallToAction thirdPartyCallToActionClass"></div>
                        <div class="fbAdTitle thirdPartyTitleClass"></div>
                    </div>
                </a>
            </div>
        </div>
    </div>
    <!-- FB End -->


    </body>
    </html>

1 个答案:

答案 0 :(得分:0)

我能够通过编辑FB提供的样板代码来解决此问题。简而言之,提供的闭包(缩小)试图:

  1. 找到展示广告的iframe元素并设置它 src和其他属性。
  2. 附加事件处理程序以侦听帖子消息&#34; message&#34;。
  3. 使用FB受众群体网络(ADNW.init())
  4. 初始化广告

    我的问题在于此代码在第1步中做出的假设。

    var b = d.currentScript || (function() {
        var c = d.getElementsByTagName('script');
        return c[c.length - 1];
    })();
    var e = b.parentElement;
    

    上面的代码试图找到这个DIV。

    <div style="display:none; position: relative;">
    

    首先尝试找到页面上最后一个脚本元素的父级。这很脆弱,在我的情况下,没有用。我文档中添加的最后一个脚本元素不是此代码所期望的那个。

    我修改了这段代码,用ID明确选择了正确的元素。

    添加了包含DIV的ID:

    <div id="fb-ad-container" style="display:none; position: relative;">
    

    简化DOM解析代码(步骤1),按ID选择此DIV:

     var e = d.getElementById("fb-ad-container");
    

    通过ID选择正确的元素,我能够减轻定位当前脚本元素的需要。脚本的其余部分按预期运行。