Angular指令中无法移除removeEventListener问题求助
解决Angular指令中无法移除F5按键监听的问题
嘿,这个问题我太熟悉啦!你遇到的核心问题是函数绑定的引用不一致——每次调用this.callback.bind(this)都会生成一个全新的函数实例。你给addEventListener传的是A函数,到removeEventListener的时候传的是另一个新生成的B函数,浏览器找不到要移除的A函数,自然就没法取消监听了。
修复步骤很简单,只需要复用同一个绑定后的函数引用:
- 在指令类里先声明一个属性,用来保存绑定好
this的回调函数:
private boundCallback: (e: KeyboardEvent) => void;
- 在
ngOnInit中,把绑定后的函数赋值给这个属性,再添加监听:
ngOnInit() { this.log("init"); // 保存绑定好this的函数引用,后续复用 this.boundCallback = this.callback.bind(this); document.addEventListener("keydown", this.boundCallback); }
- 在
ngOnDestroy里直接使用这个保存好的引用移除监听:
ngOnDestroy() { this.log("ngOnDestroy"); document.removeEventListener("keydown", this.boundCallback); }
完整修改后的指令代码:
import { Directive, ElementRef, OnDestroy, OnInit } from '@angular/core'; @Directive({ selector: '[appClickf5]' }) export class Clickf5Directive implements OnInit, OnDestroy { // 保存绑定好this的回调函数引用 private boundCallback: (e: KeyboardEvent) => void; constructor(private _el: ElementRef) { } ngOnInit() { this.log("init"); this.boundCallback = this.callback.bind(this); document.addEventListener("keydown", this.boundCallback); } ngOnDestroy() { this.log("ngOnDestroy"); document.removeEventListener("keydown", this.boundCallback); } callback(e: KeyboardEvent) { if ((e.code === "F5" || e.key === "F5") && !e.ctrlKey) { e.preventDefault(); this._el.nativeElement.click(); this.log("element clicked"); } } private log(txt: string) { const output = document.getElementById("output"); if (output) { output.innerHTML += `<br/>${txt}`; } } }
这样修改后,当你切换show状态销毁指令时,keydown监听就能被正确移除了,再按F5就不会触发按钮点击啦。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

