为何我的事件监听器无法被正确移除?
问题根源
你这段代码的核心问题是:每次调用zoom方法时,都会重新创建onMouseDown、onMouseMove、onMouseUp三个新的箭头函数实例。而removeEventListener要求传入的函数引用必须和添加时的完全一致,所以你后续调用zoom(false)时,传入的是新创建的函数,自然找不到之前添加的监听,导致移除失败。
解决方案
把事件处理函数定义为类的成员属性,确保整个实例生命周期内只存在一个函数引用,这样添加和移除时用的是同一个函数,就能正常生效了。下面提供两种实现方式:
方式1:使用箭头函数作为类成员(推荐,自动绑定this)
箭头函数会自动捕获类实例的this,无需手动绑定,而且作为类属性只会初始化一次:
class YourClass { // 将事件处理函数定义为类的私有成员属性 private onMouseDown = (event: MouseEvent) => { /* 你的原有代码 */ }; private onMouseMove = (event: MouseEvent) => { /* 你的原有代码 */ }; private onMouseUp = () => { /* 你的原有代码 */ }; public zoom(dragZoomActive: boolean): void { if (dragZoomActive) { window.addEventListener('mousedown', this.onMouseDown, true); window.addEventListener('mousemove', this.onMouseMove, true); window.addEventListener('mouseup', this.onMouseUp, true); } else { window.removeEventListener('mousedown', this.onMouseDown, true); window.removeEventListener('mousemove', this.onMouseMove, true); window.removeEventListener('mouseup', this.onMouseUp, true); } } }
方式2:普通函数+构造函数bind绑定
如果更习惯用普通函数,可以在类的构造函数中提前绑定this,确保每次调用都是同一个函数实例:
class YourClass { constructor() { // 在构造函数中绑定this,固定函数引用 this.onMouseDown = this.onMouseDown.bind(this); this.onMouseMove = this.onMouseMove.bind(this); this.onMouseUp = this.onMouseUp.bind(this); } private onMouseDown(event: MouseEvent): void { /* 你的原有代码 */ } private onMouseMove(event: MouseEvent): void { /* 你的原有代码 */ } private onMouseUp(): void { /* 你的原有代码 */ } public zoom(dragZoomActive: boolean): void { if (dragZoomActive) { window.addEventListener('mousedown', this.onMouseDown, true); window.addEventListener('mousemove', this.onMouseMove, true); window.addEventListener('mouseup', this.onMouseUp, true); } else { window.removeEventListener('mousedown', this.onMouseDown, true); window.removeEventListener('mousemove', this.onMouseMove, true); window.removeEventListener('mouseup', this.onMouseUp, true); } } }
关于bind传参的疑问
你之前担心用bind会影响event参数的传递——其实完全不用怕。bind只是修改函数的this指向,不会影响函数原本的参数接收。当事件触发时,浏览器依然会自动把MouseEvent参数传给你的处理函数,和之前箭头函数的用法完全一致。
内容的提问来源于stack exchange,提问作者SourBanana
相关产品推荐
相关产品推荐

