标签仅作语义标记,不自动高亮搜索词;安全高亮需遍历文本节点、双重转义关键词、用dom操作而非innerhtml替换,并显式声明css样式适配深色模式与可访问性。

直接写 <mark></mark> 不会自动高亮搜索词
<mark></mark> 标签本身不带搜索能力,它只负责语义标记和默认样式渲染。你看到“黄色背景”是浏览器 UA 样式的结果,不是它在帮你匹配关键词。用户搜 “React”,页面里所有 “React” 文本不会自己变成 <mark>React</mark> —— 这一步必须手动做。
用 innerHTML.replace() 动态包裹关键词很危险
这是最常见也最容易出事的写法。典型错误:el.innerHTML = text.replace(keyword, '<mark>$&</mark>');
- 用户搜
cat[0],正则没转义 →new RegExp('cat[0]')直接抛SyntaxError - 用户搜
<script>alert(1)</script>,拼进字符串后可能执行脚本 - 原文是
<code>console.log(),替换后变成<code>console.<mark>log</mark>(),<mark></mark>被撕开,DOM 解析失败 - 原文是
<img src="logo.png">,搜logo后变成<img src="<mark>logo</mark>.png">,图片挂掉
安全高亮必须只操作文本节点,别碰 HTML 字符串
核心路径:遍历文本节点 → 提取纯文本 → 匹配并创建 <mark></mark> 元素 → 插入 DOM。
- 用
document.createTreeWalker(element, NodeFilter.SHOW_TEXT)获取所有文本节点 - 跳过空节点:
node.textContent.trim() === '' - 对搜索词双重转义:
— HTML 转义:keyword.replace(/[&"'`=/]/g, c => `${c.charCodeAt(0)};`)
— 正则转义:keyword.replace(/[.*+?^${}()|[]]/g, '\$&') - 构造正则时加
gi标志:new RegExp(`(${escaped})`, 'gi') - 匹配后不用字符串替换,而是:
const mark = document.createElement('mark'); mark.textContent = match; node.replaceWith(mark);
<mark></mark> 的样式必须显式声明,否则生产环境大概率失效
浏览器默认黄色背景在 Safari 阅读模式、Outlook 邮件客户端、Windows 高对比度主题下基本不可见。不写 CSS 就上线,等于放弃可访问性。
- 至少声明:
background-color、color、padding - 深色模式适配:
@media (prefers-color-scheme: dark) { mark { background-color: #ffc107; color: #000; } } - 别写
background: none—— 它不清除background-image,应写background-color: transparent - 中文搜索要小心标点粘连,“Python” 不该匹配 “Python3” 里的 “Python”,英文需加
边界,中文得靠分词或手动定位
<mark></mark>,而是怎么确保它不炸 DOM、不执行脚本、不在暗色模式下消失、也不把“搜索词”错标成“无关词”。这些细节漏一个,高亮就从辅助功能变成体验破绽。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











