简体   繁体   English

无法在热模块更换时删除侦听器

[英]Cannot remove listener on Hot Module Replacement

I am registering a handler (for click event). 我正在注册一个处理程序(用于click事件)。 Before registering the handler, I clear the same handler so as not to register two same handlers. 在注册处理程序之前,我清除了同一处理程序,以免注册两个相同的处理程序。

I am using Webpack's Hot Module Replacement. 我正在使用Webpack的热模块更换。 Every time I change something in the JavaScript source code, part of code registering the handler is rerun. 每次我更改JavaScript源代码中的内容时,都会重新运行注册处理程序的部分代码。

However, the handler is never removed. 但是,永远不会删除该处理程序。

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');
    }
}

If I run element.removeEventListener() manually, only the last handler gets removed. 如果我手动运行element.removeEventListener() ,则仅删除最后一个处理程序。

Save the reference to the function so that you remove the same function you're adding, you'll also need to .bind(this) . 保存对函数的引用,以便删除要添加的相同函数,还需要.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');
    }
}

Update: Also remove the element when you click it and not before, so that you know that it already has a listener binded. 更新:在单击元素时(而不是在单击元素之前),也请删除该元素,以使您知道该元素已经绑定了侦听器。

A solution that might work (if it's really needed to keep the instance after changing the code with HMR) is to save the handler in the window object or a global variable that is not part of the module that's refreshed, it's not ideal but might do the trick for you since it's an exceptional case. 可能的工作(如果它真的需要保持实例改变与HMR代码后)解决方案是保存处理窗口对象或全局变量,是不是这就是刷新的模块的一部分,这是不理想,但可能会做这是您的绝招,因为这是例外情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM