标签不能直接使用,因其在高对比度模式、Outlook邮件、CSS重置后会失效;动态Markdown代码块需先转义并生成标准HTML结构再调用hljs.highlightAll();搜索高亮必须遍历文本节点并转义正则元字符与HTML特殊字符,避免DOM撕裂和XSS。

直接用 标签不行,浏览器默认样式在高对比度模式、Outlook 邮件、CSS 重置后会完全失效;动态插入的 Markdown 代码块(如 ```js)也不会被 hljs.highlightAll() 自动识别;搜索关键词高亮若用 innerHTML.replace(),轻则 DOM 撕裂,重则 XSS。
为什么 直接写不生效
它不是“加个黄底”的快捷方式,而是语义化标记。三大失效场景必须提前防住:
- Windows 高对比度模式下,系统强制清空所有背景色,
变成黑底黑字甚至不可见 - Outlook 等邮件客户端忽略 UA 样式,
渲染为纯文本 - 项目用了
* { background: transparent }这类重置规则,的默认黄色直接被抹掉
必须显式声明 background-color 和 color,且建议加 padding 和 border-radius 提升可读性。例如:高亮文本
动态搜索高亮必须遍历文本节点
el.innerHTML = el.innerHTML.replace(...) 是典型翻车操作,原因有三:
- 用户搜
a.b?c,正则未转义元字符 → 报错中断 - 用户搜
<script>alert(1)</script>→ XSS 注入 - 原文含
→ 替换后变成console.log(),DOM 解析失败console.log()
正确做法是只操作纯文本节点:
实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。
function highlightText(element, keyword) {
const walker = document.createTreeWalker(
element,
NodeFilter.SHOW_TEXT,
null,
false
);
let node;
const escapedKeyword = keyword
.replace(/[.*+?^${}()|[]\]/g, '\$&') // 正则转义
.replace(/&/g, '&')
.replace(/, '/g, '>')
.replace(/"/g, '"');
while ((node = walker.nextNode())) {
const text = node.textContent;
const regex = new RegExp(`(${escapedKeyword})`, 'gi');
if (regex.test(text)) {
const span = document.createElement('span');
span.className = 'highlight';
span.innerHTML = text.replace(regex, '<mark>$1</mark>');
node.parentNode.replaceChild(span, node);
}
}
}
Markdown 代码块动态高亮要先转结构再调用 hljs
hljs.highlightAll() 只扫描已存在的 ,对流式插入的 <pre class="brush:js;toolbar:false;">
console.log(1)
文本无感知。
关键两步缺一不可:
- 用正则提取
...
并转为标准 HTML 结构,同时对代码内容做 HTML 实体转义(&→&,→等) - 插入 DOM 后,立即调用
hljs.highlightElement(codeEl)(推荐),而非等整个容器再highlightAll()
示例转换函数:
setTimeout
或依赖 MutationObserver 延迟触发,否则用户看到的是未高亮的原始代码块,体验断层。尤其在 SSE 流式响应中,每 chunk 插入后都得立刻处理并高亮。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










