【问题标题】:Wait for Facebook Pixel Load等待 Facebook 像素加载
【发布时间】:2017-06-04 22:40:09
【问题描述】:

我想在我的 JavaScript 代码中检测 Facebook 像素的加载是否已完成。这可能吗?

Facebook Pixel Tracking 代码供参考:

<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','//connect.facebook.net/en_US/fbevents.js');
// Insert Your Facebook Pixel ID below. 
fbq('init', 'FB_PIXEL_ID');
fbq('track', 'PageView');
</script>
<!-- Insert Your Facebook Pixel ID below. --> 
<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=FB_PIXEL_ID&amp;ev=PageView&amp;noscript=1"
/></noscript>

分解一下,似乎fbq('init', ...) 导致添加script 标记并设置async 属性并将src 设置为//connect.facebook.net/en_US/fbevents.js

随后,对fbq('track', ...) 的调用会以某种方式通过一次重定向导致对图像的 HTTP GET

如何检测所有步骤是否完成,尤其是最终图片加载是否完成?

【问题讨论】:

  • @CBroe 仔细看,async 设置为 !0,其计算结果为 true。并且fbq 是内联定义的,因此即使脚本正在异步加载,对fbq 的调用也能正常工作。
  • @CBroe 我想知道它已完成的各种场景:假设用户单击将带他到不同网站的控件,然后我想延迟重定向直到加载像素.如果网络很慢并且用户立即单击了控件,则可能会发生这种情况。
  • @CBroe 请远离这个问题。你从小批评开始,引导我纠正和澄清,假设这是一个建设性的练习。最终,您选择放弃一个相当非技术性的意见,而没有任何技术上的补救措施。

标签: javascript facebook-pixel


【解决方案1】:

如果你想在成功完成FB像素加载后触发特定的FB事件,你可以使用下面的代码,代码如下:

 <script>
        function drop_fb_pixel() {
            try {
                //Drop FB Pixel
                fbq('track', 'ViewContent', {
                    content_ids: ['12'],
                    content_type: 'product' 
                });
            }
            catch (err) {
                setTimeout(function () { drop_fb_pixel(); }, 3000);

            }
        }
        $(document).ready(function () {
            drop_fb_pixel();
        });


    </script>

逻辑很简单,文件加载后该脚本会尝试触发FB事件,如果出错则在3秒后再次尝试触发事件,您可以根据自己的应用逻辑自定义事件触发的时间

【讨论】:

  • 在加载 facebook 像素后,您的代码似乎没有演示任何触发代码的方法?超时根本不是一种可靠的方法,因为网络可能很慢。
  • @user2297550,Love 的代码在加载文档时检查 Facebook Pixel 是否存在,如果不存在,则开始超时以在 3 秒后再次检查并继续执行此操作直到像素存在。即使网络很慢,它也会继续每 3 秒运行一次,直到像素存在。
  • @JohnWasham 不完全是。据我了解,代码只是修改了 DOM 以添加 &lt;script&gt; 标签或 &lt;img&gt; 标签。相关的网络请求可能需要很长时间,我无法知道该请求是否已完成。此外,我看不到它如何检查“像素存在”(存在到底是什么意思?),所以我不确定即使每 3 秒轮询一次也能检测到对 Facebook 的网络请求是否成功返回。
  • @user2297550,Facebook Pixel 代码 sn-p 首先确保 fbq 变量存在。然后它将一个 JS 文件加载到您的站点上以构建 fbq 对象的功能。实际上,您甚至可以在加载 FB JS 文件之前在 fbq 对象上运行命令,因为这些命令被添加到将在 fbq 对象加载时迭代的队列中。对于此答案中的函数,它甚至可以在您的站点中包含 FB Pixel 代码之前运行,因为它会一直尝试运行 fbq('track'...) 命令,直到 fbq 变量存在。
  • 明白。那么你真的需要改变你的问题的标题,因为它给人的印象是你只想知道什么时候加载像素。爱的回答就是这样。但是您真的想知道单个跟踪事件何时完成,对吗?
【解决方案2】:

@love-chopra 的回答还不错,但是我认为在讨论网页时使用延迟 3 秒的setTimeout() 并不是最好的解决方案。从我的 POV 来看,解决方案可能是 setInterval() 不断检查它,直到 fbevents.js 未加载。

  var fbLoaded = false;
  var tryFB = null;

  function drop_fb_pixel() {
    fbLoaded = true;
    try {
      fbq('track', 'ViewContent', {
        content_ids: ['12'],
        content_type: 'product' 
      });
    } catch (err) {
      fbLoaded = false;
    }

    if (fbLoaded) {
      clearInterval(tryFB);
    }
  }

  tryFB = setInterval(function () { 
    drop_fb_pixel();
  }, 100);

【讨论】:

    【解决方案3】:

    我对此进行了尝试。给定一个名为 myCallback 的回调函数和名为 myId 的私有 ID,请使用以下代码:

      (function wait() {
        // check for the generic script
        // easiest check to prevent race condition
        if (fbq.version > '2.0') {
          // now check for the custom script
          // `fbq.on` is now ready (`fbq.once` would be better but has a bug)
         fbq.on('configLoaded', function (name) {
            if (name === myId) {
              myCallback();
            }
          });
        } else {
          setTimeout(wait, 10);
        }
      })();
    

    myCallback 将在一切准备就绪后被调用。截至fbq.version="2.7.17";

    ,这是准确的

    参考https://github.com/poteto/ember-metrics/pull/151

    【讨论】:

    • 听好了 - Kelly Selden 摇滚。这是准确的答案,也是整个网络中唯一的答案,我找不到有关此事件的任何参考/文档,只有 JS 的脚本文件在像素请求中返回。如果有人有文档参考,请分享。
    • @naviram 谢谢。我通过缩小和阅读他们的来源找到了它。不幸的是,这些东西在他们的文档中没有。
    • @KellySelden 谢谢;这逃脱了我的注意。您确定这会解决从临时页面 像素加载后重定向的问题吗?我想建立一个登陆页面,在将访问者重定向到最终目的地之前“描绘”他们。如果是这样,我会采纳你的话和@naviram 的建议并将其标记为正确答案。
    • +1。 Kelly 和@naviram 我想知道你是否知道为什么我的 FB 跟踪像素在我尽最大努力只触发一次事件时不一致:stackoverflow.com/q/57793493/470749 谢谢。
    • 我得到“fbq.on 不是函数”。 fbq 版本 2.9.30
    【解决方案4】:

    由于 OP @user2297550 说他的最终目标是在事件触发后重定向用户,我将解释如何做到这一点(没有超时或间隔)。以前的一些答案试图检测 Facebook 像素 &lt;script&gt; 何时完成加载,但这与确定实际事件何时完成触发不同。据推测,OP 想知道PageView 事件何时完成。这个解决方案并不适合每个用例,但如果我们没有在页面上发生太多其他事情,它就会非常简单。

    为了 ping 他们的服务器并跟踪事件,Facebook 的代码创建了一个new Image() 并将其src 属性设置为https://www.facebook.com/tr/?id=XXXXXX&amp;ev=PageView&amp;{more parameters} 之类的东西。我通过检查跟踪库并找到了这个sendGET 函数发现了这一点:

    this.sendGET = function(b, c, d) {
        b.replaceEntry("rqm", "GET");
        var f = b.toQueryString();
        f = i(c, d) + "?" + f;
        if (f.length < 2048) {
            var g = new Image();
            if (d != null) {
                var h = a.getShouldProxy();
                g.onerror = function() {
                    a.setShouldProxy(!0), h || e.sendGET(b, c, d)
                }
            }
            g.src = f;
            return !0
        }
        return !1
    };
    

    我们可以通过使用我们的重定向代码填充默认的Image.onload 回调来挂钩该图像加载。结果是这样的,可以直接放在标题中普通 Facebook 像素代码的上方:

    OriginalImage = Image;
    Image = function(){
      let oi = new OriginalImage();
      oi.onload = function() {
        // if the image that loaded was indeed a Facebook pixel
        // for a "PageView" event, redirect
        if( this.src.indexOf( 'facebook.com/tr/?id=XXXXXX&ev=PageView' ) != -1 )
          window.location = 'https://example.com/redirect-here';
      };
      return oi;
    };
    

    因此,一个完整的“绘制用户并重定向”页面可能如下所示:

    <html>
    <head>
    <!-- Facebook Pixel Code -->
    <script>
      OriginalImage = Image;
      Image = function(){
        let oi = new OriginalImage();
        oi.onload = function() {
          // if the image that loaded was indeed a Facebook pixel
          // for a "PageView" event, redirect
          if( this.src.indexOf( 'facebook.com/tr/?id=XXXXXX&ev=PageView' ) != -1 )
            window.location = 'https://example.com/redirect-here';
        };
        return oi;
      };
    
      !function(f,b,e,v,n,t,s)
      {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
      n.callMethod.apply(n,arguments):n.queue.push(arguments)};
      if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
      n.queue=[];t=b.createElement(e);t.async=!0;
      t.src=v;s=b.getElementsByTagName(e)[0];
      s.parentNode.insertBefore(t,s)}(window, document,'script',
      'https://connect.facebook.net/en_US/fbevents.js');
      fbq('init', 'XXXXXX');
      fbq('track', 'PageView');
    </script>
    <noscript>
      <img height="1" width="1" style="display:none" 
           src="https://www.facebook.com/tr?id=XXXXXX&ev=PageView&noscript=1"/>
    </noscript>
    <!-- End Facebook Pixel Code -->
    </head>
    <body></body>
    </html>
    

    当然,您可以跳过 Javascript,直接从 &lt;noscript&gt; 块加载图像并添加“onload”属性,如下所示:

    <html>
    <head>
    <!-- Facebook Pixel Code -->
    <img height="1" width="1" style="display:none" 
           src="https://www.facebook.com/tr?id=XXXXXX&ev=PageView&noscript=1"
           onload="window.location = 'https://example.com/redirect-here';"/>
    <!-- End Facebook Pixel Code -->
    </head>
    <body></body>
    </html>
    

    但我猜,普通图像跟踪会降低 Facebook 识别用户的能力。

    此策略可能适用于您想要检测任意事件何时完成发送到 Facebook 的更通用的用例。但是为普通页面上的每个图像填充 onload 回调可能是不明智的。也知道 Facebook 可以随时更改他们的代码,从而破坏这一点。

    【讨论】:

    • +1 以获得很好的解释和努力——但是,你可能总是错误地认为 facebook 总是或什至通常通过导致图像加载来跟踪。现代javascript通过加载脚本而不是图像来传达事件(该方法称为“scriptsrc”,因为您插入了&lt;script src="https://facebook.com/track/someopaqueid" /&gt;因此我不认为这是正确的。
    • 没错,他们先加载JS。但该脚本只是用于稍后在页面上跟踪的库。我查看了 Facebook 的实际代码,发现了一个名为 sendGET 的函数,用于发送实际的事件请求。它创建了new Image() 并设置了它的src,这让我想到了挂钩Image 对象。我针对您的用例对此进行了测试,并且有效。始终发送跟踪事件,然后发生重定向。我会将 sendGet 定义添加到我的 OP 中,以便我们了解它是如何工作的。
    • 这是一个了不起的想法。它仍在工作。非常感谢。
    【解决方案5】:
    <script>
      $(document).ready(function () {
    
        function fbqcheck() {
          if(typeof fbq === 'undefined') {
            setTimeout(fbqcheck, 5);
          } else {
            alert('Facebook pixel loaded');
          }
        }
    
        fbqcheck();
    
      });
    </script>
    

    【讨论】:

    • 投反对票,因为这次投票而不是精确检测何时
    • 我误解了你的问题。我想你想知道 Facebook 像素加载何时完成。
    【解决方案6】:

    我知道这是一篇旧帖子,但如何将 Facebook Pixel Helper 作为 Chrome 扩展程序加载?如果您的网站上加载了像素,这会立即告诉您。


    【讨论】:

      【解决方案7】:

      因此,Kelly Seldens 解决方案看起来不错,但由于 facebook 更改了他们的库,因此对我不起作用。我的解决方案来自 Kelly Seldens,如下(适用于 facebook 2.9.15)。我将它提供给其他寻求基于加载的 facebook 像素触发操作的解决方案的人。

      就我而言,我让 Mautic 自己加载 fb 像素。我需要一种方法来检测何时发生这种情况,以便我可以触发转换事件(fb - 跟踪线索)。

      我对 Kelly 的代码所做的更改反映了两件事:

      首先我添加了条件检查是否定义了 fbq。在执行此操作之前,我收到控制台错误,每次执行超时时 fbq 都未定义。

      其次,我删除了 fbq.on 语句,因为它在 Mautic 正在加载的像素的 2.9.15 版本中不再存在。

      我最终得到的代码是:

      (function wait() {
          //first check if the fbq object is defined, then check the version (probably not needed but for good measure
      
          if ((typeof fbq !== 'undefined') && (fbq.version > '2.9')) {
              //fire off the call back / tracking event
              myCallBack(); //fbq('track', 'Lead');       
          } 
      else 
        setTimeout(wait, 10);
      })();
      

      【讨论】:

        猜你喜欢
        • 2016-12-21
        • 2013-01-12
        • 2018-03-15
        • 1970-01-01
        • 1970-01-01
        • 2012-11-05
        • 1970-01-01
        • 1970-01-01
        • 2020-06-26
        相关资源
        最近更新 更多