【问题标题】:Removing closure event listeners移除关闭事件监听器
【发布时间】:2021-08-23 04:47:38
【问题描述】:

我使用“For 循环”来创建多个“事件处理函数”。这些函数具有相同的名称。例如: 代码:

for(let x in array){
  element[x].addEventListener('click',eventhandler)
  function eventhandler(){
     bla bla....
     for(let x in array){
       element[x].removeEventListener('click',eventhandler)/*this line doesn't work*/
     }
  }
}

我现在如何删除所有这些事件侦听器? element[x].removeEventListener('click',eventhandler) 不起作用:(

【问题讨论】:

  • 将事件对象传递给处理程序,然后执行event.currentTarget.removeEventListener('click', eventhandler);。另请注意,您必须将函数拉出循环,或将定义传递给addEventListener
  • 但是对于数组中的每个'x'我必须创建一个新函数。所以该函数需要在for循环中。
  • 你不应该在数组上使用for...in,它不保证顺序并且迭代所有可枚举的属性,而是使用for...of
  • 不,你不能在循环中声明新函数,而是传递函数。传递对addEventListener 的引用的想法使得对多个事件使用相同的函数成为可能,它节省了一些内存。当您在同一范围内定义 arrayeventhandler 时,array 可以在函数中访问,您不需要循环。还要注意沙丁鱼所说的。
  • 感谢 teemu 提供的示例!因此,我了解了“事件对象”。

标签: javascript dom closures dom-events


【解决方案1】:

您可以将事件侦听器逻辑与清理逻辑分开,并像这样单独附加清理:

const cleanup = array.map((x, i) => {
  function eventhandler(){
     // bla bla....
  }

  element[i].addEventListener('click', eventhandler);
  
  return () => element[i].removeEventListener(eventhandler)
})

array.forEach((x, i) => {
  element[i].addEventListener('click', () => cleanup.forEach(y => y()));
})

【讨论】:

  • 我是初学者,所以很难理解箭头函数。如果你能用正常的函数表示法写出来,我将非常感激。
  • 箭头函数在这种情况下等价于常规函数,试试看
  • 我知道。但是我看不懂代码:(
  • 老实说,用常规函数转换我的代码会很遗憾,它只会更冗长。箭头函数只是函数的较短语法(作为总结)
  • 我只是想了解亲爱的先生。 ?