首页 > 解决方案 > 如何删除带参数的事件回调

问题描述

我有一个 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);
}

最后,我将 设置onendednull,它可以工作。

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

问题

如果设置onendednull等于的效果removeEventListener

如果没有,是否有任何其他适当的方法来删除带参数的回调?

标签: javascriptreactjsecmascript-6dom-events

解决方案


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

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

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

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

另一方面,如果你存储它的引用,你也可以使用.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);
}

推荐阅读