javascript - 无法删除热模块替换时的监听器

标签 javascript webpack webpack-hmr

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

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

最佳答案

保存对函数的引用,以便删除要添加的同一函数,您还需要 .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');
    }
}

更新: 还要在单击元素时而不是之前删除该元素,以便您知道它已经绑定(bind)了监听器。

一个可能有效的解决方案(如果确实需要在使用 HMR 更改代码后保留实例)是将处理程序保存在窗口对象或不属于窗口对象的全局变量中刷新的模块,它并不理想,但可能会为您解决问题,因为这是一个异常(exception)情况。

关于javascript - 无法删除热模块替换时的监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55483264/

相关文章:

javascript - Webpack 图像加载器仅缩小 png

webpack-dev-server - Webpack 5 : why MiniCssExtractPlugin. 加载程序不允许 HMR 工作?

css - webpack HMR 没有加载 css

visual-studio - Webpack 1.x 热模块替换模块不更新

Javascript - Google Chrome 不会更新 .js 文件

javascript - 使用 Webpack 和 svgr 加载器加载 .scss 中的 SVG

webpack 文件加载器图像到不同的目录

javascript - 如何从 HTML 表单中收集所有值?

Javascript确认取消后停止页面刷新

javascript - 是否可以删除 "Inspect Element"?