【问题标题】:Removing chrome webNavigation event删除 chrome webNavigation 事件
【发布时间】:2017-12-02 11:18:33
【问题描述】:

如何删除 chrome.webNavigation 事件?

chrome.webNavigation.onCompleted.addListener(x.bind(request.data.url), {
    url:[{urlPrefix:request.data.url+""}]
});

这就是我创建事件的方式,这就是我试图在“x”函数中删除事件的方式,

chrome.webNavigation.onCompleted.removeListener(arguments.callee);

但奇怪的是,它并没有删除监听器,而是每次调用 addlistener 时,我都会不断添加越来越多的监听器,而不会删除最后一个。

编辑: 所以似乎不可能删除 .bind() 函数创建的匿名函数。

【问题讨论】:

  • 我刚刚尝试了与window.addEventListener() 类似的方法,但同样失败。
  • 注意:在 chrome(55) 中使用 addEventListener(也在 firefox(50) 和 opera(42) 中,但在 safari (yet)、edge 或 ie 中没有),有一个更简单的获得“一次性”事件监听器的方法...window.addEventListener('whatever', fn, { once: true}) - 至于.onCompleted.addListener - 有一个相当简单的方法可以解决这个问题(我想,会添加答案)

标签: javascript google-chrome google-chrome-extension


【解决方案1】:

.bind() 创建一个新的bound function 调用您正在绑定的函数,设置适当的this 并将参数调整为您指定的参数,以及调用绑定函数时使用的任何参数。

您可以通过polyfill for .bind() on MDN 了解其工作原理。

下面是一些示例代码,证明arguments.callee 不是绑定函数:

function toBeBound(arg1) {
    console.log('arguments.callee:', arguments.callee);
    console.log('arguments.callee === arg1:', arguments.callee === arg1);
    console.log('arg1:', arg1);
}
var bound = toBeBound.bind(null);
bound(bound);

you create with x.bind(request.data.url) 的绑定函数是调用x() 的不同函数。 不是x。因此,当您在 x 函数中并尝试:

chrome.webNavigation.onCompleted.removeListener(arguments.callee);

你有效地做的是:

    chrome.webNavigation.onCompleted.removeListener(x);

因为x是当时的arguments.callee,已经被.bind()创建的函数调用了。但是,您添加为侦听器的函数是 绑定函数

你需要一个绑定函数的引用来移除监听器

实现您想要的方法是引用绑定函数,您可以在x() 中使用它来删除侦听器。一种简单的方法是添加您的侦听器,例如:

var boundX = x.bind(request.data.url);
chrome.webNavigation.onCompleted.addListener(boundX, {
    url:[{urlPrefix:request.data.url+""}]
});

然后,在您的 x() 函数中,您可以使用以下方法删除侦听器:

chrome.webNavigation.onCompleted.removeListener(boundX);

显然,对于您的实际代码,您如何实现这一点可能需要更复杂。但是,鉴于您提供的代码量最少,任何更复杂的东西都只是我的猜测。在某些情况下,我保留了包含对我用作侦听器的绑定函数的引用的数组或对象。

只调用一次监听器

如果您的用例是您总是想要在事件第一次触发时删除事件侦听器,那么 Jaromanda X 在their answer 中提供了一个很好的解决方案来实现这一点。它基本上是一个基于 ES6 的实现,它构建了一个调用事件监听器的通用方法的标准方法(在addEventListener 能够specify once as an option 之前)。它所做的是创建一个函数来自动保存对侦听器的引用。

【讨论】:

    【解决方案2】:

    没有用 addListener/removeListener 尝试过这个,只有 addEventListener/removeEventListener - 但是我认为逻辑是合理的

    function once(ev, filter, listener) {
        const fn = (...args) => {
            listener(...args);
            ev.removeListener(fn);
        }
        ev.addListener(fn, filter);
    }
    

    而且,你的情况是

    once(chrome.webNavigation.onCompleted, {url:[{urlPrefix:request.data.url+""}]}, x.bind(request.data.url));
    

    【讨论】:

      猜你喜欢
      • 2015-02-06
      • 1970-01-01
      • 1970-01-01
      • 2015-07-13
      • 2012-06-16
      • 1970-01-01
      • 2013-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多