【问题标题】:How can you remove or block event listeners from third party JavaScript tracking & analytics?如何从第三方 JavaScript 跟踪和分析中删除或阻止事件侦听器?
【发布时间】:2015-11-21 11:56:30
【问题描述】:

我经营一个电子商务网站,我们有各种第三方 JavaScript,它们向链接和表单添加点击处理程序,然后插入延迟以确保跟踪通过。通过消耗 CPU 并运行 for 或 while 循环来插入延迟,直到某个日期过去 350 毫秒(Marketo / Munchkin)或 Visual Website Optimizer 的 500 毫秒。加起来几乎是 1 秒!

有时,延迟可能很好,因此跟踪可能更可靠。但是,当您单击我们网站上的大多数链接时,我们不希望发生这种情况,因为它会为用户增加最多 1 秒的延迟。有了这么大的延迟,我们已经完成了所有其他性能优化!

很遗憾,我们需要这些脚本的很多功能(例如 Visual Website Optimizer 和 Marketo),所以我们无法删除它们。

鉴于我没有对它们的引用,是否可以删除他们添加的处理程序或阻止它们触发?

【问题讨论】:

  • 要删除事件,您可以使用unbind
  • 您是否发现在某些情况下为什么/在哪些地方您的等待时间会加倍?正如你所说,它不应该超过 500 毫秒。
  • 我深入挖掘发现有 500 ms (VWO) + 350 ms (Marketo)。基本上,任何对链接(标签)的点击都会被跟踪。对于 Visual Website Optimizer,即使他们没有跟踪任何内容,这种情况也会天真地发生,但如果没有 A/B 测试处于活动状态,这种情况可能会消失(但无论如何,拥有它有什么意义)。对于 Marketo 来说,这似乎一直都是。 VWO 还通过表单提交开始了无限旋转。当我看到我的加载微调器滞后于我们的 AJAX 登录时,我注意到了这一点,并通过至少推迟分析调用解决了 CPU 旋转造成的一些卡顿,但仍然 - 非常可悲。

标签: javascript jquery analytics web-analytics marketo


【解决方案1】:

您可以使用unbind 删除事件。

如果您需要知道事件名称或类型,可以通过Chrome Dev Tools查看

另一种方法是捕获事件并stop the propagation

编辑: 如果事件不是用 jQuery 启动的,你可以使用removeEventListenerset null the property event

【讨论】:

  • 取消绑定只会删除 jQuery 事件。
  • 最初,我的前提是您无法获得对处理程序的引用。我现在发现我有 2 个可以不同处理的案例。 VWO 使用 jQuery onmousedown,所以我可以使用 unbind 来删除它的跟踪。由于它没有命名空间,因此您最终可能会意外删除其他处理程序。我不确定是否有一种简单的方法可以找到正确的方法,但也许可以通过使用内部 jQuery 方法来获取您可能猜到的参考。当有跟踪时,你无法消除延迟,但我已经要求他们添加一个变量,或者我正在考虑代理他们的脚本来重写它。
  • 对于 Marketo,我认为不可能删除它们的 onbeforeunload,因为它是使用 addEventListener 添加的,并且我们没有对处理程序的引用。但是,我找到了一种解决方法,我可以将延迟设置为 0 毫秒,这样我就不需要禁用跟踪。这符合我的用例,但一般来说,我的问题的答案似乎是你不能删除你没有参考的东西。
【解决方案2】:

如果没有对处理函数的引用,您无法删除事件侦听器,但您可以做的是克隆元素。

var elements = document.getElementsByTagName('a');
for(var i =0 ; i < elements.length; i++){
    var cloned = elements[i].cloneNode(true);
    elements[i].parentNode.replaceChild(cloned, elements[i])
}

【讨论】:

  • 这似乎不可行,因为 VWO 和 Marketo 会跟踪页面上所有的表单提交和链接点击。由于动态插入的新元素会被跟踪到,因此它们可能正在使用事件委托。我的猜测是,如果没有您提到的处理程序函数的引用,我很不走运。鉴于我无法克隆所有内容,并且无论如何都可能委派事情,我只是卡住了吗?
【解决方案3】:

另一种解决方法可能是更改 setTimeout 功能以在没有延迟或延迟较小的情况下工作

window.oldSetTimeout = window.setTimeout;
window.setTimeout = function(func, delay) {
   //change the delay value here
   return window.oldSetTimeout(function() {
       func();
   }, delay);
};

【讨论】:

  • 覆盖默认方法(或原型)通常是一种不好的做法。这将导致整个页面上出现大量难以发现的行为
  • 同意,但正如我所说,这是一种解决方法。使用 3rd 方脚本的结果
  • 使用变通方法通常会期望以某种肮脏/复杂的方式解决问题,但这只会破坏更多对我的修复
  • 这些脚本和许多跟踪脚本添加延迟的方式很丑陋。他们基本上使CPU加速。例如,我跟踪了缩小的 Visual Website Optimizer 代码,他们将其调用为 500 以暂停 500 毫秒:function V(a) { for (var b = a, a = a + (new Date).getTime(); (new Date).getTime() &lt; a; ) ; h(Ha, b) } 因为它不是全局的,并且是由第三方在闭包中定义的,所以我没有不认为我可以改变这一点。 setTimeout 未使用。
【解决方案4】:

你可以使用纯javascript来移除事件监听器,

在你的程序开始时调用一个函数来移除事件监听器,像这样

var domElement = document.getElementById('elementWithEventListener');
domElement.removeEventListener('click',listener)

是的,你必须找出哪些听众被解雇了。

查看Event listeners 了解更多信息。

【讨论】:

  • 如果可以的话,这似乎是我会做的,但我提到我没有对侦听器的引用,因为我不控制添加侦听器的脚本。这是我的主要挑战。
  • 你知道监听器附着在哪些元素上吗?
  • 是的。 Marketo 中的所有链接,并使用 VWO 在 body 上监听 mousedown 以捕捉所有冒泡的内容。对于我的具体问题,我实际上已经让 VWO 添加了一个很棒的新配置选项,我在 Marketo 的 Munchkin sn-p 中找到了一个。至于一般问题,似乎没有办法removeEventListener 没有对侦听器本身的引用。 developer.appcelerator.com/question/127638/…stackoverflow.com/questions/26845535/….
猜你喜欢
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
  • 2017-01-23
  • 1970-01-01
  • 2019-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多