Javascript removeEventListener 不起作用

IT技术 javascript events addeventlistener
2021-02-03 21:44:27

我有以下代码来添加 eventListener

 area.addEventListener('click',function(event) {
              app.addSpot(event.clientX,event.clientY);
              app.addFlag = 1;
          },true);

它按预期正常工作......后来在另一个函数中我尝试使用以下代码删除事件侦听器

 area.removeEventListener('click',function(event) {
              app.addSpot(event.clientX,event.clientY);
              app.addFlag = 1;
          },true);

但是偶数监听器没有被删除..为什么会发生?我的removeEventListener()有什么问题吗?注意:这里的区域类似于 document.getElementById('myId')

6个回答

这是因为这两个匿名函数是完全不同的函数。removeEventListener的参数不是对先前附加的函数对象的引用。

function foo(event) {
              app.addSpot(event.clientX,event.clientY);
              app.addFlag = 1;
          }
 area.addEventListener('click',foo,true);
 area.removeEventListener('click',foo,true);
如果有人使用类this.onClick = this.onClick.bind(this)在任何侦听器之前尝试类似的事情,那么btn.addEventListener('click', this.onClick),最后btn.removeEventListener('click', this.onClick)
2021-03-22 21:44:27
@Herrgott 要将参数传递给处理程序函数,您可以使用 currying: foo = (argumentToPass) => (event) => { doSomething(); }, then xyz.addEventListener('click', foo('myarg'), true);foo('myarg')会返回另一个函数argumentToPass设置为myarg请记住在实际代码中保持对 fn 的引用:-)
2021-03-26 21:44:27
@joseluisq 你能解释一下 bind(this) 是什么意思吗?它有效,但我不知道为什么
2021-03-27 21:44:27
+1 正确。bind(this)将更改签名。因此,始终将函数分配给使用函数APIvar后绑定thisbind以便varremoveListener. 你会在typescript中看到这个问题更明显
2021-04-04 21:44:27
那将不允许您传递函数参数 fe foo(1)
2021-04-07 21:44:27

我发现对于 windows 对象,最后一个参数“true”是必需的。如果没有捕获标志,则删除不起作用。

您在两次调用中都创建了两个不同的函数。所以第二个函数与第一个函数没有任何关系,引擎可以删除该函数。改用函数的通用标识符。

var handler = function(event) {
              app.addSpot(event.clientX,event.clientY);
              app.addFlag = 1;
          };
area.addEventListener('click', handler,true);

稍后您可以通过调用删除处理程序

area.removeEventListener('click', handler,true);

在 React 函数组件中,确保使用useCallback(() => {}钩子定义回调如果你不这样做,每次重新渲染时回调将是不同的,并且该removeEventListener方法将不起作用。

const scrollCallback = useCallback(() => { // do sth. }
window.addEventListener("scroll", scrollCallback, true);
window.removeEventListener("scroll", scrollCallback, true);

要删除它,请将函数存储在变量中,或者简单地使用命名函数并将该函数传递给removeEventListener调用:

function areaClicked(event) {
    app.addSpot(event.clientX, event.clientY);
    app.addFlag = 1;
}

area.addEventListener('click', areaClicked, true);
// ...
area.removeEventListener('click', areaClicked, true);
但是我如何将参数(此处为事件)传递给该函数..这就是我使用匿名函数的原因
2021-03-11 21:44:27
它由浏览器传递。是否单独定义函数并不重要。
2021-03-11 21:44:27
警告:我发现我的方法有什么问题。removeEventListener() 方法仅适用于 NAMED FUNCTIONS。它不适用于匿名函数!当我编辑代码以考虑到这一点时,一切都按计划进行。您必须在您的闭包中定义一个 NAMED 函数,并使用闭包传递的参数返回对其实例的引用。这样做,removeEventListener() 就可以完美运行。
2021-04-07 21:44:27