用 <mark> 标签配合 DOM 节点操作是段落内动态高亮搜索最语义正确、安全且可访问的方式;需遍历文本节点、双重转义关键词、显式声明样式并支持中文词边界匹配。

用 `` 标签配合 DOM 节点操作,是实现段落内动态高亮搜索最语义正确、安全且可访问的方式。直接拼字符串或改 `innerHTML` 看似简单,但极易引发 XSS、DOM 结构破坏和样式失效——尤其在 ` ` 这类包含内联元素(如 ``、``)的文本容器中。 段落可能嵌套多种标签,比如: 正确做法是遍历 ` ` 内所有纯文本节点: 用户输入可能是 立即学习“前端免费学习笔记(深入)”; 转义分两步: 构造正则时加 默认黄色背景在暗色模式、高对比度设置、邮件客户端或 Safari 阅读模式下基本不可见,甚至被完全剥离。 至少写清三项基础样式: 加上暗色模式适配: 中文无空格分隔,直接搜“服务”会误命中“微服务”“服务器”,影响阅读体验。 用 Unicode 边界断言模拟词边界: 这个方案无需引入分词库,兼顾准确性与轻量性,适合大多数文档级搜索场景。只操作文本节点,不碰 HTML 结构
<p>我们推荐使用<strong>React</strong>开发应用</p>。若用 innerHTML.replace() 搜索 “React”,会把 `` 标签撕开,变成 `React` 以外的非法结构,甚至导致渲染异常或事件丢失。
document.createTreeWalker(pElement, NodeFilter.SHOW_TEXT) 获取全部文本节点node.textContent.trim() === '')textContent 执行匹配,创建 `` 元素插入,再用 node.replaceWith(mark)
关键词必须双重转义,防崩防XSS
foo[bar] 或 <script>alert(1)</script>,不处理就会触发正则报错或脚本执行。
.、*、[ 等元字符转为字面量,例如 keyword.replace(/[.*+?^${}()|[]]/g, '\$&')
& → &," → ",覆盖 & "'`=/ 六个关键字符gi 标志(全局 + 不区分大小写),中文建议补 u 支持 Unicode:new RegExp(`(${escaped})`, 'giu')。样式必须显式声明,别信浏览器默认
background-color(如 #ffeb3b 或深色模式下的 #ffca28)color(确保与背景足够对比,WCAG AA ≥4.5:1)padding(避免文字贴边,提升可读性)
@media (prefers-color-scheme: dark) { mark { background-color: #ffca28; color: #121212; } }
中文需加词边界,避免“服务”匹配“服务器”
(?<=[\s\u4e00-\u9fa5]|^)(前是空白、汉字或开头)(?=[\s\u4e00-\u9fa5]|$)(后是空白、汉字或结尾)new RegExp(`(?<=[\s\u4e00-\u9fa5]|^)${escaped}(?=[\s\u4e00-\u9fa5]|$)`, 'giu')



















