Vue触发另一事件时移除DOM事件监听器(DevExtreme场景)
解决DevExtreme Vue文本框onFocusOut无法移除事件监听器的问题
你的问题核心是事件移除时引用的DOM元素与绑定事件的元素不一致,导致removeEventListener失效。以下是具体原因和解决方案:
核心原因
- DOM结构依赖不稳定:你通过
childNodes[1].childNodes[0].childNodes[0]链式获取元素,DevExtreme组件在交互过程中可能会重新渲染内部DOM结构,导致onFocusOut中获取的元素和onFocusIn时绑定事件的元素不是同一个对象。 - 重复绑定未被正确清理:如果多次触发focusIn,会重复绑定事件,而focusOut只移除一次,残留的监听器依然生效。
解决方案
1. 改用稳定的DOM选择器获取内部元素
DevExtreme的文本框内部输入元素有固定的类名.dx-texteditor-input,直接用这个选择器获取元素,避免依赖不稳定的childNodes结构。
2. 保存DOM元素引用到Vue实例
在data中定义变量存储绑定事件的元素引用,确保focusOut时操作的是同一个元素。
修改后的完整代码示例
// Vue组件data部分 data() { return { // 存储绑定事件的DOM元素引用 activeTextEditorElement: null } }, methods: { moveCursorToFarLeftStupidBug() { // 你的业务逻辑代码 } }, // DevExtreme dxTextBox的事件配置 onFocusIn(e) { // 用稳定选择器获取内部输入元素 this.activeTextEditorElement = e.element.querySelector('.dx-texteditor-input'); if (this.activeTextEditorElement) { // 先移除一次再绑定,避免重复绑定 this.activeTextEditorElement.removeEventListener("click", this.moveCursorToFarLeftStupidBug); this.activeTextEditorElement.removeEventListener("mouseover", this.moveCursorToFarLeftStupidBug); this.activeTextEditorElement.addEventListener("click", this.moveCursorToFarLeftStupidBug); this.activeTextEditorElement.addEventListener("mouseover", this.moveCursorToFarLeftStupidBug); } }, onFocusOut() { if (this.activeTextEditorElement) { // 移除事件监听器 this.activeTextEditorElement.removeEventListener("click", this.moveCursorToFarLeftStupidBug); this.activeTextEditorElement.removeEventListener("mouseover", this.moveCursorToFarLeftStupidBug); // 清空引用,避免内存泄漏 this.activeTextEditorElement = null; } }
额外注意事项
- 确保
moveCursorToFarLeftStupidBug是定义在Vue组件methods中的普通函数,不要用箭头函数定义,保证函数引用的一致性。 - 如果需要处理多个文本框,可以把元素引用改成对象,用文本框的唯一标识作为键来存储对应元素。
内容的提问来源于stack exchange,提问作者Baraiboapex
相关产品推荐
相关产品推荐

