删除匿名事件侦听器

IT技术 javascript greasemonkey addeventlistener userscripts
2021-02-01 20:15:29

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

element.addEventListener(event, function(){/* do work here */}, false);

不更换元素?

6个回答

除非您在创建时存储了对事件处理程序的引用,否则无法彻底删除事件处理程序。

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

我想知道为什么 addeventlistener 不返回这样的引用以供 removeeventlistener 将来使用...
2021-03-16 20:15:29
请注意,根据stackoverflow.com/a/27107765/377022,在 Chrome 控制台中,您可以使用该getEventListeners功能
2021-03-21 20:15:29
@乔当然。更新官方接受的答案可能会很好,以便将来将此作为参考的人(就像我一样)了解新的发展。
2021-03-25 20:15:29
确实如此,这就是您保存的内容。
2021-04-04 20:15:29
@Joe 和迟到的用户:至少在某些情况下addEventListener返回undefined例如在 BroadcastChannel 上下文中。
2021-04-11 20:15:29

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

element.addEventListener("click", function clicked() {
    element.removeEventListener("click", clicked, false);
}, false);
您可能想要添加callee自 ES5 起已弃用的内容(请参阅mdnSO
2021-03-18 20:15:29
@fxm:谢谢。我不记得为什么我最初使用arguments.callee命名函数表达式应该可以正常工作,所以我编辑了我的答案。
2021-03-22 20:15:29
Brock 是对的,这是一个关于用户脚本的问题,但还是不错的答案,我投了赞成票!
2021-03-23 20:15:29
这仅在您首先添加事件侦听器时才有效——您可以修改原始的 listener() 代码。由于这是一个 Greasemonkey 应用程序,这是不可能的。即使更改了基页脚本,您也只会添加另一个匿名侦听器。
2021-04-08 20:15:29
@Brock:哦,我以为目的是删除您添加的侦听器。我不知道有什么方法可以删除您没有添加并且没有参考其功能的侦听器。
2021-04-12 20:15:29

匿名绑定事件监听器

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

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


匿名委托事件侦听器

一个警告是委托的事件侦听器,或父元素上的事件侦听器,它们监视每个与其子元素上的一组条件匹配的事件。解决这个问题的唯一方法是更改​​元素以使其不满足委托事件侦听器的标准。

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

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

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

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

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

element.removeEventListener('click',element.fn, false);

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

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

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

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

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

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

就像这个解决方案我要使用它。不知道这是否重要,但之后仍然会引用该函数,例如调用 element.fn() 仍将返回该函数的结果。如果不清理,这可能是内存问题吗?
2021-03-23 20:15:29

您可以尝试覆盖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));
    }
};

ps.:不推荐,但可以解决问题(尚未测试)

或者,您可以替换EventTarget.prototype.addEventListener. 这对我有用
2021-03-22 20:15:29