双击高亮需阻止默认行为、手动构造Range并确保目标为纯文本节点;surroundContents()仅支持单Text节点内范围,跨节点时应克隆内容分段处理;优先用语义化mark标签而非span,注意XSS防护与兼容性。

window.getSelection() 返回的是当前选区,不是双击触发的独立事件;直接监听 dblclick 并调用 surroundContents() 会失败——因为双击时浏览器默认已触发一次原生选中,此时 getSelection().rangeCount 可能为 0(尤其在非文本节点上),或选区被重置。
必须先阻止默认行为、手动构造 Range,并确保目标是纯文本节点。
双击后高亮失败?检查是否在非文本节点上触发
常见错误现象:Range.surroundContents() 报错 “The range has partially selected a non-Text node” 或静默失败。
原因:用户双击的是 生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力:
- 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面;
- 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”;
- 提及位于 `apps/console/src/featur 这是最常踩的坑:双击选中跨多个文本节点的内容(例如段落中有 很多人用 双击高亮真正难的不是代码行数,而是边界判断:文本节点是否可写、Range 是否干净、
、
getSelection() 可能返回空或跨节点范围。
event.target.nodeType === Node.TEXT_NODE 判断是否点在文本上;如果不是,需递归查找第一个子文本节点(如 event.target.childNodes[0])document.createTreeWalker(event.target, NodeFilter.SHOW_TEXT) 获取所有后代文本节点,再逐个检查 range.intersectsNode(textNode)
),应跳过,不报错也不执行高亮
surroundContents() 报错 “The range contains multiple nodes” 怎么办加粗文字),getRangeAt(0) 返回的 Range 会横跨 Text 和 Element,无法直接包裹。
surroundContents() —— 它只接受完全位于单个 Text 节点内的 Rangerange.cloneContents() 提取纯文本,再遍历原始 Range 覆盖的所有文本节点,对每个节点内匹配的子串分别创建 mark 元素并替换document.execCommand('hiliteColor', false, 'yellow')(仅 Chrome/Firefox 支持,已废弃但尚可用)用
mark 替代 span 包裹更安全且语义正确document.createElement('span') 加 style="background: yellow",但这绕过了语义、可访问性与默认样式继承逻辑。
mark 是 HTML5 原生语义标签,屏幕阅读器会读作“高亮文本”,且默认有黄色背景、无需额外 CSSmark 样式;旧版 Safari 中 mark > strong 的文字颜色可能被覆盖——需加防御性 CSS:mark > * { color: inherit !important; }
class="highlight-keyword"),而不是内联 style,避免污染和维护困难document.createTextNode(match) 设置内容,而不是拼接字符串,防止 XSS(如用户双击了 <script>alert(1)</script>)mark 是否被父级样式压制、暗色模式下颜色是否还可见。这些细节不验证,上线后第一周就会收一堆“点了没反应”的反馈。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










