mark是唯一语义正确、无障碍友好的高亮方案;不能用innerhtml.replace()因会引发xss、dom解析失败和正则报错;安全做法须用treewalker遍历文本节点、双重转义关键词、动态创建mark元素并显式声明适配暗色模式的css样式。

mark 是唯一语义正确、浏览器原生支持、无障碍友好的文本高亮方案,其他标签(如 span、strong)加样式只是视觉模拟,不传达“上下文相关性”。
为什么不能直接用 innerHTML.replace() 做关键词高亮
这是最常见也最危险的写法,三处必崩:
- 用户搜
[a-z],正则没转义 →new RegExp(keyword)报错中断 - 用户搜
<script>alert(1)</script>→ 拼进字符串后可能执行脚本(XSS) - 原文是
<code>console.log()→ 替换后变成<code>console.<mark>log</mark>(),mark被撕开,DOM 解析失败
安全高亮必须只操作文本节点,用 TreeWalker
核心路径:遍历纯文本内容 → 双重转义关键词 → 创建 mark 元素 → 插入 DOM
- 用
document.createTreeWalker(element, NodeFilter.SHOW_TEXT)获取所有文本节点 - 跳过空节点:
node.textContent.trim() === '' - HTML 转义:
keyword.replace(/[&"'`=/]/g, c => `${c.charCodeAt(0)};`) - 正则转义:
keyword.replace(/[.*+?^${}()|[]]/g, '\$&') - 匹配后创建真实元素:
const mark = document.createElement('mark'); mark.textContent = match;,再用node.parentNode.replaceChild(mark, node)
mark 标签必须显式声明 CSS,否则在暗色模式/高对比度下完全不可见
浏览器默认黄色背景在以下场景等于没写:
- Windows 高对比度模式强制重置为黑底白字
- Outlook 邮件客户端忽略所有 UA 样式
- CSS 重置规则(如
* { background: transparent })清空默认背景
至少声明这三项:background-color、color、padding;border-radius 是刚需,避免文字紧贴边缘。深色模式必须手动适配:@media (prefers-color-scheme: dark) { mark { background-color: #ffca28; color: #121212; } }
多关键词高亮时,长度排序和文本节点遍历缺一不可——否则 "JavaScript" 和 "Script" 会嵌套错乱;mark 不是快捷样式工具,它是语义开关,关掉它,读屏器就听不到“marked text”,搜索引擎也收不到上下文信号。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











