mark 是唯一传达上下文高亮语义的元素;必须转义正则特殊字符、遍历文本节点操作、显式声明样式、按长度降序处理多关键词,并兼顾中文词界与深色模式适配。

mark 标签不是“加个黄底”的快捷方式,它是唯一能向浏览器、读屏器和搜索引擎传达“这是当前上下文相关高亮”的语义化元素。直接用 innerHTML 拼接或忽略转义,轻则样式消失、重则触发 XSS。
为什么不能直接 innerHTML.replace() 包裹关键词
这是最常见也最危险的做法。比如用户搜 [a-z],未经处理就传进 new RegExp(keyword) 会直接报错;搜 <script>alert(1)</script> 则执行脚本。
- 正则特殊字符(
.、*、?、[、]等)必须先转义:keyword.replace(/[.*+?^${}()|[]\]/g, '\$&') - 原始文本若含 HTML(如
<code>console.log),字符串替换会撕开标签,导致 DOM 解析失败 - 大小写不敏感匹配(
i标志)后硬写'<mark>$&</mark>',会丢失原文本大小写
安全高亮必须遍历文本节点,而非操作 innerHTML
正确路径是只在纯文本节点(node.nodeType === 3)里操作,跳过所有元素节点,避免污染结构。
- 用
textContent获取原始文本,天然规避 XSS - 用
document.createElement('mark')创建节点,再用appendChild()插入 - 对匹配项单独包裹,其余部分用
document.createTextNode()保持原样 - 多关键词时,务必按长度降序排序(先长后短),防止短词嵌入已闭合的
mark内
mark 样式必须显式声明,不能依赖浏览器默认
默认黄色背景在阅读模式、Outlook 邮件、深色主题、CSS 重置(如 * { background: transparent })下会彻底失效。
- 至少写死这四条:
background-color、color、padding、border-radius - 深色模式需补充
@media (prefers-color-scheme: dark)媒体查询 - 别只写
background: none,它漏掉background-image等隐式值 - 中文高亮要小心全半角和边界:正则匹配需加
或自定义中文词界逻辑,否则cat会误中education
真正难的不是把字变黄,而是让高亮在 XSS 防御、DOM 安全、语义传达、可访问性、暗色适配这五层约束下稳定生效——漏掉任何一层,都可能让搜索页对盲人用户“不可见”,或在邮件里“完全透明”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











