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

时间:2019-04-02 20:43:31

标签: javascript webpack webpack-hmr

我正在注册一个处理程序(用于click事件)。在注册处理程序之前,我清除了相同的处理程序,以免注册两个相同的处理程序。

我正在使用Webpack的热模块更换。每次我更改JavaScript源代码中的内容时,都会重新运行注册处理程序的部分代码。

但是,永远不会删除处理程序。

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(),只会删除最后一个处理程序。

1 个答案:

答案 0 :(得分:1)

保存对函数的引用,以便删除要添加的相同函数,还需要.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对象或不属于该对象的全局变量中。刷新过的模块,虽然不理想,但可能会帮到您,因为这是例外情况。