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

JS如何实现将页面中属于指定数组的所有匹配单词文字改为红色

问题原因

你的代码存在3个核心问题:

  • 每次替换都基于最开始保存的原始HTML字符串,没有同步更新该变量,前序替换结果会被后续操作直接覆盖
  • 插入带样式的标签后,HTML字符串长度发生变化,基于原始字符串计算的匹配索引全部失效
  • 直接传入字符串调用matchAll不会开启全局匹配,只会返回第一个匹配结果

优化后的实现方案

推荐直接用全局正则替换实现,逻辑更简洁,也能规避索引偏移的问题,修改后的JS代码如下:

// 可选:如果搜索词包含. + *等正则特殊字符,需要先调用该方法转义
function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

function change() {
  const body = document.querySelector("body");
  // 提取所有纯文本节点,避免误修改HTML标签属性、script标签内的内容
  const textNodes = [];
  const nodeIterator = document.createNodeIterator(body, NodeFilter.SHOW_TEXT, null);
  let currentNode;
  while (currentNode = nodeIterator.nextNode()) {
    if (currentNode.parentElement.tagName !== 'SCRIPT') {
      textNodes.push(currentNode);
    }
  }

  const searching = ["Lorem","nemo"];
  // 遍历每个文本节点单独替换
  textNodes.forEach(node => {
    let text = node.textContent;
    searching.forEach(keyword => {
      // 构建全局匹配正则
      const reg = new RegExp(escapeRegExp(keyword), 'g');
      text = text.replace(reg, `<span style="color: red;">$&</span>`);
    });
    // 替换原文本节点为带样式的新内容
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = text;
    while (tempDiv.firstChild) {
      node.parentNode.insertBefore(tempDiv.firstChild, node);
    }
    node.remove();
  });
}

change();

代码说明

  • 用document.createNodeIterator筛选纯文本节点,不会误改标签属性、JS代码里的同名字符串
  • 全局正则g修饰符会匹配当前文本节点内所有对应关键词,$&指代匹配到的原文内容
  • 每个文本节点单独处理,不会出现匹配位置偏移的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:06:06