删除已经存在的事件监听器

Remove already existing event listener

我正在尝试从对象中删除一个已经存在的事件侦听器。我尝试了几种方法(使用 jQuery .off().unbind(), 标准 removeEventsListeners()),但如文档中所述,它们只能删除以前添加的方法?

使用 Chrome 调试器,我可以查看并删除指定的事件侦听器,

此外,当尝试通过 jQuery _data() 函数列出事件侦听器时,它不会列出事件。几个小时以来一直在寻找答案。

有人可以帮忙吗?任何解决方法?

编辑: 我必须保留一些,所以无法克隆

如果事件处理程序是使用 addEventListener 添加的,除非您有对添加的处理程序函数的引用,否则无法删除它。我认为一定是这样,因为如果它与 jQuery 的 on (or various shortcuts for it), off 挂钩就可以,而你说它不起作用。

解决此问题的一种方法是 用克隆元素替换 元素。当您使用 DOM 的 cloneNode, you don't copy its event handlers. So if you start out with element, then you can clone it, use insertBefore to insert the clone, then use removeChild 克隆元素以删除原始元素时:

var newElement = element.cloneNode(true); // true = deep
element.parentNode.insertBefore(newElement, element);
element.parentNode.removeChild(element);

当然,这确实是一种解决方法。正确的做法是一开始就不要设置处理程序,或者保留对它的引用(如果您以后需要能够将其删除)。


在评论中你说你不能那样做,并问:

Is there a way to add a new event listener that blocks the already existing one?

只有你能到达,否则不行,你不能。

您不能添加阻止现有处理程序的新处理程序(不是以跨浏览器的标准方式),但如果您可以在添加另一个处理程序之前添加您的处理程序,则可以通过使用来阻止它被调用stopImmediatePropagation:

// Your handler
document.getElementById("target").addEventListener("click", function(e) {
  console.log("Your handler");
  e.stopImmediatePropagation();
  e.stopPropagation();
});

// The one that you're trying to prevent
document.getElementById("target").addEventListener("click", function(e) {
  console.log("Handler you're trying to prevent");
});
<div id="target">Click me</div>

因此,例如,如果在 window load 事件中添加了另一个处理程序,或者 jQuery ready 处理程序,您也许可以获得您的处理程序首先,将您的代码放在相关元素之后的 script 标记中。

一个非常简单的方法是使用 .innerHTML 不向父元素附加任何内容。请注意,这会破坏作为父元素后代的所有事件侦听器。下面是一个例子(点击2销毁附加到1的事件监听器):

const d1 = document.querySelector('#d1');
d1.addEventListener('click', () => console.log(123));

const d2 = document.querySelector('#d2');
d2.addEventListener('click', () => d1.parentNode.innerHTML += '');
<div><button id="d1">1</button></div>
<div><button id="d2">2</button></div>