无法在热模块更换时删除侦听器
Cannot remove listener on Hot Module Replacement
我正在注册一个处理程序(用于点击事件)。在注册处理程序之前,我清除了同一个处理程序,以免注册两个相同的处理程序。
我正在使用 Webpack 的热模块替换。每次我在 JavaScript 源代码中更改某些内容时,注册处理程序的部分代码都是 re运行。
但是,永远不会删除处理程序。
export default class TaskHandlers {
// Called from index.js
registerAddTaskClick(addTaskElementId) {
let element = document.querySelector(`#${addTaskElementId}`);
if (element !== null) {
// Never clears the handler
element.removeEventListener('click', this.handleAddTaskClick);
// Keeps piling on new handlers on every HMR.
element.addEventListener('click', this.handleAddTaskClick);
}
}
handleAddTaskClick(event) {
console.log('Clicked');
}
}
如果我 运行 element.removeEventListener()
手动,只有最后一个处理程序被删除。
保存对函数的引用,以便删除您正在添加的相同函数,您还需要 .bind(this)
。
export default class TaskHandlers {
constructor() {
this.element = document.querySelector(`#${addTaskElementId}`);
this.handleAddTaskClick = this.handleAddTaskClick.bind(this);
}
// Called from index.js
registerAddTaskClick(addTaskElementId) {
if (this.element !== null) {
this.element.addEventListener('click', this.handleAddTaskClick);
}
}
handleAddTaskClick(event) {
this.element.removeEventListener('click', this.handleAddTaskClick);
console.log('Clicked');
}
}
更新:
当您单击它时而不是之前删除该元素,以便您知道它已经绑定了一个侦听器。
可能可行的解决方案(如果在使用 HMR 更改代码后确实需要保留实例)是将处理程序保存在 window 对象中或一个全局变量,它不是被刷新的模块的一部分,它不是理想的,但可能对你有用,因为它是一个例外情况。
我正在注册一个处理程序(用于点击事件)。在注册处理程序之前,我清除了同一个处理程序,以免注册两个相同的处理程序。
我正在使用 Webpack 的热模块替换。每次我在 JavaScript 源代码中更改某些内容时,注册处理程序的部分代码都是 re运行。
但是,永远不会删除处理程序。
export default class TaskHandlers {
// Called from index.js
registerAddTaskClick(addTaskElementId) {
let element = document.querySelector(`#${addTaskElementId}`);
if (element !== null) {
// Never clears the handler
element.removeEventListener('click', this.handleAddTaskClick);
// Keeps piling on new handlers on every HMR.
element.addEventListener('click', this.handleAddTaskClick);
}
}
handleAddTaskClick(event) {
console.log('Clicked');
}
}
如果我 运行 element.removeEventListener()
手动,只有最后一个处理程序被删除。
保存对函数的引用,以便删除您正在添加的相同函数,您还需要 .bind(this)
。
export default class TaskHandlers {
constructor() {
this.element = document.querySelector(`#${addTaskElementId}`);
this.handleAddTaskClick = this.handleAddTaskClick.bind(this);
}
// Called from index.js
registerAddTaskClick(addTaskElementId) {
if (this.element !== null) {
this.element.addEventListener('click', this.handleAddTaskClick);
}
}
handleAddTaskClick(event) {
this.element.removeEventListener('click', this.handleAddTaskClick);
console.log('Clicked');
}
}
更新: 当您单击它时而不是之前删除该元素,以便您知道它已经绑定了一个侦听器。
可能可行的解决方案(如果在使用 HMR 更改代码后确实需要保留实例)是将处理程序保存在 window 对象中或一个全局变量,它不是被刷新的模块的一部分,它不是理想的,但可能对你有用,因为它是一个例外情况。