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

JavaScript:外层contenteditable div的blur事件触发问题求助

解决contenteditable div与内部input的blur事件触发问题

这确实是浏览器聚焦机制的正常表现——当焦点在子元素input上时,父元素div(即使设置了contenteditable)并不会被视为“失去焦点”,因为焦点只是在它的内部元素上转移了。不过有几个实用的办法可以实现你想要的效果:

方法1:监听input的blur,手动触发div的blur

当input失去焦点时,我们可以检查新的焦点是否还在div内部,如果不在,就手动触发div的blur事件:

<div id="editable-div" contenteditable="true">
  <input type="text" id="inner-input">
</div>
const editableDiv = document.getElementById('editable-div');
const innerInput = document.getElementById('inner-input');

innerInput.addEventListener('blur', () => {
  // 用setTimeout延迟判断,确保浏览器完成焦点切换
  setTimeout(() => {
    if (!editableDiv.contains(document.activeElement)) {
      editableDiv.dispatchEvent(new Event('blur'));
    }
  }, 0);
});

// 正常监听div的blur事件
editableDiv.addEventListener('blur', () => {
  console.log('div 已失去焦点');
  // 这里写你的业务逻辑
});

方法2:使用focusout事件(更推荐)

focusout是冒泡事件,会在元素或其子元素失去焦点时触发。我们可以直接在div上监听这个事件,然后通过relatedTarget判断新焦点是否还在div内部:

const editableDiv = document.getElementById('editable-div');

editableDiv.addEventListener('focusout', (e) => {
  // e.relatedTarget 是即将获得焦点的元素
  if (!editableDiv.contains(e.relatedTarget)) {
    console.log('div 实际失去了焦点');
    // 执行原blur事件的逻辑
  }
});

这个方法更简洁,不需要额外监听子元素的事件,直接利用事件冒泡的特性就能准确判断div是否真正失去了焦点。

方法3:给div添加tabindex(可选)

给div设置tabindex="-1"让它可以被主动聚焦,这样div本身会有更明确的焦点状态,但可能需要额外处理input聚焦时div的焦点转移问题:

<div id="editable-div" contenteditable="true" tabindex="-1">
  <input type="text" id="inner-input">
</div>

这种方式适合需要更精细控制焦点流转的场景,但相对前两种方法会复杂一些。


内容的提问来源于stack exchange,提问作者john Smith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:27:17