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

如何修改JavaScript代码实现关键词精准高亮而非部分匹配

解决关键词精准高亮与页面崩溃问题

原代码存在两个核心问题:一是会误高亮包含关键词的部分单词(比如cores里的core),二是直接替换innerHTML会破坏DOM结构、丢失事件绑定,甚至引发页面崩溃。以下是修复后的代码及说明:

const keywordList = ["AMD", "Intel", "ATI", "core", "code", "error"];

// 转义正则特殊字符,避免关键词里的特殊符号干扰正则匹配
function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

// 遍历文本节点实现精准高亮,不破坏原有DOM结构
function highlightKeywords(node, keywords) {
  // 跳过已经高亮的mark标签,避免重复处理
  if (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'MARK') return;
  // 如果是元素节点,递归处理它的子节点
  if (node.nodeType === Node.ELEMENT_NODE) {
    for (const child of node.childNodes) {
      highlightKeywords(child, keywords);
    }
    return;
  }

  // 处理文本节点
  if (node.nodeType === Node.TEXT_NODE) {
    const text = node.textContent;
    if (!text.trim()) return;

    // 构建带单词边界的正则,一次性匹配所有关键词,全局不区分大小写
    const pattern = new RegExp(`\\b(${keywords.map(escapeRegExp).join('|')})\\b`, 'gi');
    const fragments = [];
    let lastIndex = 0;

    let match;
    while ((match = pattern.exec(text)) !== null) {
      // 把匹配前的普通文本加入片段
      if (match.index > lastIndex) {
        fragments.push(document.createTextNode(text.slice(lastIndex, match.index)));
      }
      // 创建高亮标签包裹匹配到的关键词
      const mark = document.createElement('mark');
      mark.textContent = match[0];
      fragments.push(mark);
      lastIndex = pattern.lastIndex;
    }

    // 加入剩余的普通文本
    if (lastIndex < text.length) {
      fragments.push(document.createTextNode(text.slice(lastIndex)));
    }

    // 替换原文本节点,用文档片段减少DOM操作次数
    if (fragments.length > 1) {
      const frag = document.createDocumentFragment();
      fragments.forEach(item => frag.appendChild(item));
      node.parentNode.replaceChild(frag, node);
    }
  }
}

// 启动高亮
highlightKeywords(document.body, keywordList);

关键修复点说明

  • 精准匹配单词:用\b正则单词边界确保只匹配独立单词,不会命中cores这类包含关键词的长单词;同时通过escapeRegExp处理关键词里的特殊字符(比如如果关键词是code.,不会被当作正则语法解析)。
  • 避免DOM破坏:不再直接替换innerHTML,而是递归遍历文本节点,只修改文本内容,保留原有DOM结构和事件绑定;用文档片段批量插入节点,减少重绘次数,提升性能还能避免崩溃。
  • 防止重复高亮:跳过已存在的<mark>标签,避免同一关键词被多次包裹。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 10:05:31