如何在Angular 4中移除EventListeners

6

我需要在鼠标滚轮事件被触发后立即删除它的监听器。我尝试了以下代码,但它并没有成功删除监听器。

export class HomeComponent implements OnInit {

    constructor() {}

    ngOnInit() {
       document.querySelector("#section-one").addEventListener("wheel", () => this.myFunction1(), true);
    }

    myFunction1() {
      alert();
      document.querySelector("#section-one").removeEventListener("wheel", this.myFunction1, true);
      console.log("Done!");
    }
}

有什么建议吗?
4个回答

15

根据 文档

使用不能识别任何当前已注册的 EventListener 的参数调用 removeEventListener() 不会产生任何效果。

你的代码不应该起作用。

可能的解决方法如下:

wheelHandler: any;

ngOnInit() {
    this.wheelHandler = this.myFunction1.bind(this);
    document.querySelector("#section-one").addEventListener("wheel", this.wheelHandler, true);
}

myFunction1() {
    alert();
    document.querySelector("#section-one").removeEventListener("wheel", this.wheelHandler, true);
    console.log("Done!");
}

其中wheelHandler是指向相同处理程序实例的函数。

要了解更多Angular方法的解决方案,请参见:

但据我所知,useCapture参数尚未得到支持。 因此,它始终为false


{btsdaf} - cyr_x
1
{btsdaf} - yurzui
{btsdaf} - cyr_x
{btsdaf} - yurzui
我测试了它,但当我多次访问组件时,我面临着多个调用的问题,因为removeEventListener不像我期望的那样工作。有人有什么建议吗? - qleoz12

7
您可以使用HostListener修饰符绑定事件监听器,但这仅适用于宿主元素。如果您想为子元素添加和删除侦听器,则必须使用Renderer2.listen方法。该方法返回一个函数以移除事件监听器。
@Component( {
  template: '<div #sectionOne></div>'
})
export class myComponent {
  private _listeners = [];

  @ViewChild('sectionOne')
  public section: ElementRef<any>;

  constructor(private _renderer: Renderer2) {}

  ngAfterViewInit() {
    this._listeners.push(
      this._renderer.listen(this.section.nativeElement, 'click', this.handler.bind(this))
    );
  }

  ngOnDestroy() {
    this._listeners.forEach(fn => fn());
  }

  public handler() {
  }
}

目前 Angular 不支持 useCapture 参数。更多信息,请参见 issue


{btsdaf} - yurzui
{btsdaf} - cyr_x

1
问题可能是当您将类方法用作回调函数时,this 不再指向回调函数中的类。
使用以下代码替换以添加事件侦听器:
document.querySelector("#section-one")
  .addEventListener("wheel", () => this.myFunction1(), true);

请注意,this.myFunction1 已变为 () => this.myFunction1()。换句话说,我将回调函数的名称包装在 lambda 中。
删除监听器的代码保持不变:
document.querySelector("#section-one").removeEventListener("wheel", this. myFunction1, true);

最后,也是最重要的,为什么你要像那样使用事件监听器?这绝对不是Angular的方式。


{btsdaf} - Karthik Samyak
我的错。看起来removeEventListener()确实需要至少2个参数。所以你可以保留原来的代码。 - AngularChef
{btsdaf} - Karthik Samyak
{btsdaf} - AngularChef
Thank you for your time. - Karthik Samyak

0
你可以不使用接受的答案中提到的bind,而是通过将函数声明为一个带有箭头的类属性来实现这一点。
ngOnInit() {
    document.querySelector("#section-one").addEventListener("wheel", this.wheelHandler, true);
}

wheelHandler = () => {
    alert();
    document.querySelector("#section-one").removeEventListener("wheel", this.wheelHandler, true);
    console.log("Done!");
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接