【问题标题】:How to remove event callback with parameters如何删除带参数的事件回调
【发布时间】:2021-05-07 07:06:01
【问题描述】:

我有一个 Web 应用程序,页面 A 有视频,而页面 B 没有。该视频在完成视频播放时具有onended 事件。我尝试在使用removeEventListener 卸载组件之前删除该事件,否则将在我切换到页面 B 后触发视频结束事件。

但是,我找不到删除带参数回调的正确方法。 我使用了箭头函数和绑定来传递参数,但是这两种方法使得事件移除是不可能的。

componentDidMount() {
  // 1st trial: anonymous function cannot be removed
  this.video.onended = () => this.videoOnEndedCallback(params);
  // 2nd trial: bind() creates new function, cannot be referenced either
  this.video.onended = this.videoOnEndedCallback.bind(this, params);
}

componentWillUnmount() {
  this.video.removeEventListener('ended', this.videoOnEndedCallback);
}

最后,我将onended 设置为null,它就可以工作了。

componentWillUnmount() {
  this.video.onended = null;
}

问题

如果将onended设置为null等于removeEventListener的效果?

如果没有,有没有其他合适的方法来移除带参数的回调?

【问题讨论】:

  • removeEventListener 删除使用addEventListener 添加的侦听器,但未直接分配为处理程序,即element.onclick = () => alert('hi');。分配null 是删除直接分配的处理程序的正确方法。使用事件侦听器删除侦听器时,您必须传递 removeEventListeneraddEventListener 之前添加的确切函数的引用。
  • @JacobSmit 你的意思是this.video.removeEventListener('ended', callback) 只适用于this.video.addEventListener('ended', callback)
  • 是的。 addEventLister / removeEventListener 用于Event Listenerselement.onclick 或类似的是Event Handler
  • 同样,函数必须是相同的引用,所以const eventListener = () => alert('test'); element.addEventListener('click', eventListener); element.removeEventListener('click', eventListener); 将按预期运行,但element.addEventListener('click', () => alert('test')); element.removeEventListener('click', () => alert('test')); 不会。
  • 看来我需要一个额外的变量来保持对箭头函数的引用。 this.arrowCallback = () => this.callback(params) 然后,我可以参考this.arrowCallbackremoveEventListener

标签: javascript reactjs ecmascript-6 dom-events


【解决方案1】:

如果事件侦听器是使用命名的事件属性(在本例中为.onended)设置的,则可以通过重新分配来更改它,并通过将其设置为null 来移除它。 (这种方式只能为每个事件设置一个监听器。)

另一种方式.addEventListener()可以为同一个事件注册多个事件监听器,不能更改,只能被.removeEventListener()移除(需要引用设置的监听器)。

这两种方式相互配合,但无论哪种方式,您都必须为每个侦听器选择用于添加/更改/删除该侦听器的方法。

在您的情况下,使用事件侦听器属性更容易,就像您 .bind() 函数一样,您将没有对新函数的引用,因此您将无法通过 @987654326 将其删除@。

另一方面,如果你存储它的引用,你也可以使用.addEventListener()/.removeEventListener()方法:

constructor(){
  this.boundVideoOnEndedCallback = this.videoOnEndedCallback.bind(this, params); //You can also use the arrow-function-version here
}
componentDidMount() {
  this.video.addEventListener('ended', this.boundVideoOnEndedCallback)
}

componentWillUnmount() {
  this.video.removeEventListener('ended', this.boundVideoOnEndedCallback);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-04
    • 2011-02-28
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 2019-04-15
    • 2017-12-25
    相关资源
    最近更新 更多