You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue触发另一事件时移除DOM事件监听器(DevExtreme场景)

解决DevExtreme Vue文本框onFocusOut无法移除事件监听器的问题

你的问题核心是事件移除时引用的DOM元素与绑定事件的元素不一致,导致removeEventListener失效。以下是具体原因和解决方案:

核心原因

  1. DOM结构依赖不稳定:你通过childNodes[1].childNodes[0].childNodes[0]链式获取元素,DevExtreme组件在交互过程中可能会重新渲染内部DOM结构,导致onFocusOut中获取的元素和onFocusIn时绑定事件的元素不是同一个对象。
  2. 重复绑定未被正确清理:如果多次触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 08:50:29