EventListener可以通过取消它的回调函数来删除吗?

Can an EventListener be removed by nullifying its callback function?

本文关键字:删除 函数 回调 可以通过 取消 EventListener      更新时间:2023-09-26

我想知道事件侦听器是否可以通过取消其回调函数来删除?

简化的例子:

var somefunction = function() {
  // some code
}
window.addEventListener(eventType, somefunction, false); 

现在,设置somefunction = null;会删除上面的EventListener,还是会简单地把它变成一个僵尸EventListener?

实际的代码是在Firefox(覆盖类型)插件中使用的,我正在考虑(自动)删除unload事件上的EventListeners的替代方法,除了明显的:

window.removeEventListener(eventType, somefunction, false); 

Update:请注意这是Firefox插件代码的一部分。本例中的事件类型是'popupshowing',不能被取消,因为它会破坏浏览器的功能。

提前感谢你的帮助期待(备选)建议

removeEventListener是正确的选择。

同样,通过将某些变量设置为null,您实际上不会使函数无效。变量只分配了一个引用(指向非pod对象,如函数)。为了说明这一点,请考虑以下内容:

var a = function() { alert("called"); };
setTimeout(a, 1000); // Will still alert!
var b = a;
a = null; // What you called `nullify`....
console.log(this.a, "a" in this); // null, true
delete this.a; // Actually remove the property from the global scope.
// `a` is really dead at this point!
b(); // will still alert, too.

如果你想避免一些removeEventListener调用,我会使用一些辅助函数:

let { addEventListenerUnload, removeEventListenerUnload } = (function() {
  let tracked = [];
  addEventListener("unload", function removeTracked() {
    removeEventListener("unload", removeTracked);
    for (let t of tracked) {
      try {
        removeEventListener(t.type, t.fn, t.capture);
      }
      catch (ex) {}
    }
    tracked.length = 0;
  });
  return {
    addEventListenerUnload: function(type, fn, capture) {
      addEventListener(type, fn, capture);
      tracked.push({type: type, fn: fn, capture: capture});
    },
    removeEventListenerUnload: function(type, fn, capture) {
      tracked = tracked.filter(e => e.type != type || e.fn != fn || e.capture != capture);
      removeEventListener(type, fn, capture);
    }
  };
})();

(包括Firefox支持的一些ECMA-6内容,但您可以轻松转换。另外,removeEventListenerUnload可能根本不需要,所以可以省略它。另外,当在覆盖脚本中使用这个时,确保给它一个唯一的名字,以避免与其他代码冲突。

我不认为设置回调函数为空将删除eventlistener,你仍然有eventlistener附加,你可以使用removeEventListener或设置eventType为空,如:

window.eventType = null;