删除匿名事件侦听器

eri*_*old 45 javascript greasemonkey addeventlistener userscripts

无论如何要删除像这样添加的事件监听器:

element.addEventListener(event, function(){/* do work here */}, false);
Run Code Online (Sandbox Code Playgroud)

没有替换元素?

Joe*_*Joe 20

除非在创建时存储对事件处理程序的引用,否则无法干净地删除事件处理程序.

我通常会将这些添加到该页面上的主对象,然后您可以在完成该对象时迭代并干净地处理它们.

  • 我想知道为什么addeventlistener没有返回这样的参考以供将来使用removeeventlistener ... (4认同)
  • @Joe,对于迟到的用户:至少在某些情况下,“addEventListener”返回“undefined”。例如在 BroadcastChannel 上下文中。 (2认同)

ick*_*fay 16

你可以像这样删除事件监听器:

element.addEventListener("click", function clicked() {
    element.removeEventListener("click", clicked, false);
}, false);
Run Code Online (Sandbox Code Playgroud)

  • 这只适用于您首先添加事件侦听器 - 您可以修改原始侦听器()代码.由于这是一个Greasemonkey应用程序,这是不可能的.即使更改了基页脚本,您也只能添加*另一个*匿名侦听器. (6认同)

小智 12

匿名绑定事件侦听器

删除元素的所有事件侦听器的最简单方法是将其分配outerHTML给自身.这样做是通过HTML解析器发送HTML的字符串表示,并将解析后的HTML分配给元素.因为没有传递JavaScript,所以不会有绑定的事件侦听器.

document.getElementById('demo').addEventListener('click', function(){
    alert('Clickrd');
    this.outerHTML = this.outerHTML;
}, false);
Run Code Online (Sandbox Code Playgroud)
<a id="demo" href="javascript:void(0)">Click Me</a>
Run Code Online (Sandbox Code Playgroud)


匿名委派的事件侦听器

一个警告是委托事件监听器或父元素上的事件监听器,它监视与其子项上的一组条件匹配的每个事件.过去的唯一方法是将元素更改为不符合委托事件侦听器的条件.

document.body.addEventListener('click', function(e){
    if(e.target.id === 'demo') {
        alert('Clickrd');
        e.target.id = 'omed';
    }
}, false);
Run Code Online (Sandbox Code Playgroud)
<a id="demo" href="javascript:void(0)">Click Me</a>
Run Code Online (Sandbox Code Playgroud)


Man*_*ngo 10

老问题,但这里有一个解决方案。

严格来说,除非您存储对该函数的引用,否则您无法删除匿名事件侦听器。由于使用匿名函数的目的大概不是创建新变量,因此您可以将引用存储在元素本身中:

element.addEventListener('click',element.fn=function fn() {
    //  Event Code
}, false);
Run Code Online (Sandbox Code Playgroud)

稍后,当您想要删除它时,您可以执行以下操作:

element.removeEventListener('click',element.fn, false);
Run Code Online (Sandbox Code Playgroud)

请记住,第三个参数 ( false) 的值必须添加事件侦听器的值相同

然而,问题本身又引出了另一个问题:为什么?

使用.addEventListener()而不是更简单的.onsomething()方法有两个原因:

首先,它允许添加多个事件侦听器。在有选择地删除它们时,这会成为一个问题:您可能最终会命名它们。如果您想将它们全部删除,那么@tidy-giant 的outerHTML解决方案非常好。

其次,您确实可以选择捕获而不是冒泡事件。

如果这两个原因都不重要,您很可能决定使用更简单的onsomething方法。


Oll*_*ams 8

是的,您可以删除匿名事件侦听器:

const controller = new AbortController();

document.addEventListener(
  "click",
  () => {
    // do function stuff
  },
  { signal: controller.signal }
);
Run Code Online (Sandbox Code Playgroud)

然后您可以像这样删除事件侦听器:

controller.abort();
Run Code Online (Sandbox Code Playgroud)


w35*_*l3y 5

您可以尝试覆盖element.addEventListener并做任何您想做的事情。
就像是:

var orig = element.addEventListener;

element.addEventListener = function (type, listener) {
    if (/dontwant/.test(listener.toSource())) { // listener has something i dont want
        // do nothing
    } else {
        orig.apply(this, Array.prototype.slice.apply(arguments));
    }
};
Run Code Online (Sandbox Code Playgroud)

ps.: 不推荐,但可以解决问题(还没有测试过)