Safari中contentEditable div聚焦时自动选中内容快速失选问题
问题原因
Safari的内置事件处理逻辑和Chrome、Firefox存在差异:你在focus事件回调中完成选区设置后,Safari还会继续执行默认的点击定位逻辑,把选区重置到鼠标点击的位置,就会出现内容短暂高亮后选区消失的问题。
解决方案
方案1:异步执行选区设置逻辑
将选区添加的逻辑放到异步队列,等Safari的默认事件处理流程执行完成后再执行,即可避免被默认逻辑覆盖,修改后的代码如下:
const selection = window.getSelection(); // Shouldn't be undefined, but I guess could be? if (selection) { const range = document.createRange(); range.selectNodeContents(event.target); selection.removeAllRanges(); // 延迟执行,等待Safari默认选区处理完成 setTimeout(() => { selection.addRange(range); }, 0); }
如果不需要兼容非常旧的浏览器版本,也可以用requestAnimationFrame替代setTimeout,执行时机更精准:
const selection = window.getSelection(); // Shouldn't be undefined, but I guess could be? if (selection) { const range = document.createRange(); range.selectNodeContents(event.target); selection.removeAllRanges(); requestAnimationFrame(() => { selection.addRange(range); }); }
方案2:添加mousedown事件拦截(可选优化)
如果你的使用场景中用户主要通过点击触发聚焦,可以额外添加mousedown事件处理,避免异步执行带来的轻微选区闪烁:
// 给你的contentEditable元素绑定该事件 editableDiv.addEventListener('mousedown', (e) => { // 仅在元素未聚焦时拦截默认行为,不会影响用户聚焦后选中部分内容的操作 if (document.activeElement !== e.target) { e.preventDefault(); e.target.focus(); } })
以上方案均兼容点击聚焦、键盘Tab聚焦两种触发方式,可在所有主流浏览器正常运行。
内容的提问来源于stack exchange,提问作者tettoffensive
相关产品推荐
相关产品推荐

