如何使用JS/CSS为pre标签添加行号且保留highlight.js语法高亮
解决方案
方案1:使用highlight.js配套行号扩展(无侵入实现)
无需自行改写DOM结构,不会破坏已生成的hljs-*高亮标签,只需做如下配置:
- 引入highlight.js后同步引入配套行号插件
- 初始化代码如下:
// 先执行highlight.js语法高亮初始化 hljs.highlightAll(); // 执行行号插件初始化 hljs.initLineNumbersOnLoad();
- 给需要展示行号的
<pre>标签添加line-numbers类,配套CSS样式参考:
.hljs-ln-numbers { text-align: right; color: #999; border-right: 1px solid #e5e5e5; padding-right: 12px; user-select: none; } .hljs-ln-code { padding-left: 12px; }
方案2:自定义JS/CSS实现(无需额外插件)
核心逻辑是在highlight.js完成高亮后再处理行号,操作innerHTML而非innerText保留原有高亮标签:
JS逻辑
document.addEventListener('DOMContentLoaded', () => { // 遍历所有代码块 document.querySelectorAll('pre code').forEach(codeBlock => { // 按换行符拆分高亮后的HTML内容 const lineList = codeBlock.innerHTML.split(/\n/); // 逐行包裹line类span,保留原有高亮标签 codeBlock.innerHTML = lineList .filter(line => line.trim() !== '') // 过滤空行避免生成无效行号 .map(line => `<span class="code-line">${line}</span>`) .join('\n'); }); });
配套CSS样式
pre code { counter-reset: line-count; font-family: Consolas, Monaco, monospace; } .code-line::before { counter-increment: line-count; content: counter(line-count); display: inline-block; width: 2em; margin-right: 1em; color: #888; text-align: right; user-select: none; }
核心注意点
- 严格保证执行顺序:先运行highlight.js高亮逻辑,再运行行号插入逻辑,顺序颠倒会导致行号标签被高亮逻辑覆盖
- 处理行内容时操作
innerHTML,不可直接改写innerText,否则会清空已生成的高亮标签
内容的提问来源于stack exchange,提问作者Elbert Villarreal
相关产品推荐
相关产品推荐

