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

输入文本时如何正确高亮十六进制代码?解决重复叠加问题

解决输入时十六进制代码重复高亮的问题

问题原因

你遇到的重复叠加问题,是因为每次keyup触发时,代码会把已经被<mark>包裹的十六进制代码再次匹配替换。比如第一次把#fff变成<mark>#fff</mark>,第二次会匹配这个标签里的#fff,直接嵌套成<mark><mark>#fff</mark></mark>,多次按键后就会无限叠加标签。

解决方案1:先清除旧高亮,再重新渲染

最简单的修复方式是每次处理前,先把已有的<mark>标签还原成原始文本,再重新匹配高亮:

$(".hwt-highlights").on("keyup", function() {
  // 第一步:清除已有的高亮,把<mark>标签还原成原始的十六进制文本
  const originalContent = this.innerHTML.replace(
    /<mark style="background-color: #([a-fA-F0-9]+)">#\1<\/mark>/g,
    "#$1"
  );

  // 第二步:重新匹配合法的十六进制颜色代码并高亮
  const hexRegex = /#([a-fA-F0-9]{3,6})/g; // 只匹配3/6位的标准颜色十六进制
  const highlightedContent = originalContent.replace(
    hexRegex,
    '<mark style="background-color: #$1">#$1</mark>'
  );

  this.innerHTML = highlightedContent;
});

优化说明:

  • 正则改成#([a-fA-F0-9]{3,6}),只匹配符合规范的3位或6位十六进制颜色代码,避免误匹配#123abcdef这类超长内容。
  • 还原逻辑精准匹配之前生成的<mark>标签,确保不会误删其他内容。

解决方案2:只处理纯文本节点(更稳妥)

如果页面里有其他自定义标签,方案1的正则还原可能有风险,可以选择直接遍历纯文本节点,只处理未被<mark>包裹的文本,从根源避免重复叠加:

$(".hwt-highlights").on("keyup", function() {
  const hexRegex = /#([a-fA-F0-9]{3,6})/g;

  // 递归遍历节点,只处理纯文本和非mark元素
  function processNode(node) {
    if (node.nodeType === Node.TEXT_NODE) {
      const text = node.textContent;
      if (!hexRegex.test(text)) return;

      // 把文本拆分成「普通文本+十六进制代码」的片段
      const fragments = text.split(hexRegex);
      const frag = document.createDocumentFragment();

      fragments.forEach((part, index) => {
        if (index % 2 === 0) {
          // 偶数位是普通文本,直接创建文本节点
          frag.appendChild(document.createTextNode(part));
        } else {
          // 奇数位是匹配到的十六进制代码,创建mark标签
          const mark = document.createElement("mark");
          mark.style.backgroundColor = `#${part}`;
          mark.textContent = `#${part}`;
          frag.appendChild(mark);
        }
      });

      // 用新的片段替换原文本节点
      node.parentNode.replaceChild(frag, node);
    } else if (node.nodeType === Node.ELEMENT_NODE && node.tagName !== "MARK") {
      // 跳过mark标签,只处理其他元素的子节点
      for (let i = 0; i < node.childNodes.length; i++) {
        processNode(node.childNodes[i]);
        i++; // 替换节点后,子节点列表长度变化,调整索引
      }
    }
  }

  processNode(this);
});

额外优化建议:

因为keyup事件会在每次按键时触发,频繁处理DOM可能影响性能,可以加个防抖函数,延迟100-200ms再执行高亮逻辑,避免连续按键时重复触发:

function debounce(func, delay = 150) {
  let timer;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(() => func.apply(this, arguments), delay);
  };
}

// 绑定防抖后的处理函数
$(".hwt-highlights").on("keyup", debounce(function() {
  // 这里放上面的高亮逻辑
}));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:25:26