You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用HTML包裹字符串局部内容实现代码自定义着色?

问题

我想在<code>元素中渲染按钮的HTML标记,同时用不同的<span>元素给代码的特定部分加颜色(比如尖括号设为蓝色,引号设为绿色)。

用正则表达式和HTML字符编码处理后,现在能包裹目标内容,但遇到了瓶颈:生成的<span>被浏览器解析成了真实的HTML元素,而我需要这些<span>作为代码字符串的高亮容器——准确来说,是让<span>实现语法高亮,同时里面的代码内容能正确显示成HTML标记。

当前生成的错误输出如下:

<span class="chev"><<span>button id=<span class="quote">"">"<<span>btn<span class="quote">"">"<<span> class=<span class="quote">"">"<<span>btn btn-primary tru-btn<span class="quote">"">"<<span> data-value=<span class="quote">"">"<<span>btn-primary<span class="quote">"">"<<span> type=<span class="quote">"">"<<span>button<span class="quote">"">"<<span><span class="chev">><<span>Button<span class="chev"><<span>/button<span class="chev">><<span> 

当前代码

JavaScript

generateHTMLBlock = () => {
  let someButton = document.querySelector('div').innerHTML,
    modBtnCode = someButton.replace(/^.\s+|\s+$/gm, ''),
    btnMarkup = modBtnCode.replace(/(.{100})/g, "$1\r");
  encodeElement = (output) => {
    return output.replace(/</g, '&lt;span class=&quot;chev&quot;&gt;&amp;#60;&lt;span&gt;')
      .replace(/>/g, '&lt;span class=&quot;chev&quot;&gt;&amp;#62;&lt;span&gt;')
      .replace(/"/g, '&lt;span class=&quot;quote&quot;&gt;&amp;#34;&lt;/span&gt;');
  let code = encodeElement(btnMarkup);
  document.getElementsByTagName('code').appendChild(code);
};

CSS

.btn-primary:not(disabled):not(.disabled),
.btn-secondary:not(disabled):not(.disabled) {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  max-width: fit-content;
  padding: 0.338rem 1.5rem;
  margin: 0;
  overflow: hidden;
  background: black;
  border-radius: .625rem;
  border-width: .125rem;
  border: 1px solid transparent;
  border-color: black;
  box-shadow: none;
  font-family: arial;
  color: white;
  font-size: 16px;
  font-weight: 400;
  text-align: center;
  vertical-align: middle;
  text-transform: none;
  user-select: none;
  line-height: 2.2rem;
  letter-spacing: .25px;
  text-decoration: none !important;
  cursor: pointer;
  transition: all .3s ease-in-out;
}

pre {
  padding: 1rem;
  margin-bottom: 0;
  width: 100%;
  height: 6em;
}

code {
  display: block;
  color: black;
  width: 100%;
  height: 100%;
  border: 1px solid red;
}

.quote {
  color: green;
}

.chev {
  color: blue;
}

HTML

<div>
  <button id="btn" class="btn btn-primary" data-value="btn-primary" type="button">Button</button>
</div>
<pre>
  <code></code>
</pre>

解决方案

问题出在编码逻辑搞反了:你需要先把原始HTML转成实体,再用真实的<span>包裹这些实体,而不是把<span>也转成实体。正确步骤如下:

  1. 转义原始HTML:先把按钮的HTML代码转成HTML实体,确保浏览器把它们当作文本显示,而非真实标签。
  2. 添加高亮容器:对转义后的实体(比如&lt;、&gt;、&quot;)进行替换,用真实的<span>标签包裹,让浏览器解析这些span来应用颜色样式。
  3. 插入到code元素:把处理后的HTML字符串作为innerHTML插入,而非创建文本节点。

修改后的JavaScript代码:

generateHTMLBlock = () => {
  // 获取按钮的HTML代码
  let someButton = document.querySelector('div').innerHTML;
  // 去除首尾空白
  let modBtnCode = someButton.replace(/^\s+|\s+$/gm, '');
  // 第一步:转义原始HTML为实体
  let escapedMarkup = modBtnCode
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;');
  
  // 第二步:用span包裹需要高亮的实体
  let highlightedCode = escapedMarkup
    .replace(/&lt;/g, '<span class="chev">&lt;</span>')
    .replace(/&gt;/g, '<span class="chev">&gt;</span>')
    .replace(/&quot;/g, '<span class="quote">&quot;</span>');
  
  // 第三步:插入到code元素中
  document.querySelector('code').innerHTML = highlightedCode;
};

// 调用函数
generateHTMLBlock();

说明

  • 先转义:把<>和"转成对应的HTML实体,确保原始代码以文本形式展示。
  • 再包裹:用带样式类的span包裹这些实体,让浏览器解析span并应用颜色。
  • 用innerHTML插入:既保留span的样式效果,又能正确显示HTML代码内容。

这样处理后,<code>元素里会正确显示按钮的HTML代码,同时尖括号为蓝色、引号为绿色,完全符合需求。

内容的提问来源于stack exchange,提问作者Eric Guest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:37:02