纯JS文本高亮函数Bug修复请求:连续关键词匹配异常
修复JavaScript文本高亮函数
realcar的连续关键词匹配Bug 问题概述
这款纯JavaScript实现的realcar函数具备无框架依赖、大小写不敏感、支持HTML标签内容高亮的特性,但搜索连续关键词(如"word high")时存在Bug:第二个关键词会被替换为文本片段中最后一个空格后的其他词汇,而非目标搜索词。
Bug根源分析
- 数组引用污染:
RegExpUNICO直接引用了原关键词数组wordss,在匹配循环中不断向其中push匹配到的文本,导致后续正则表达式被无关内容污染。 - 错误的位置定位:使用
nodeValue.indexOf(parts[n-1])获取高亮文本起始位置,若文本存在重复片段,会取到第一个匹配位置,导致高亮内容错位。 - 冗余的正则重构:在匹配后重复构建正则的逻辑完全多余,反而打乱了原有的关键词匹配规则。
修复后的完整代码
HTMLElement.prototype.realcar = function(word) { const el = this; // 处理关键词:去重、过滤短词(长度>2) const wordss = word.trim().sanitiza().split(" ").filter(word1 => word1.length > 2); // 避免空关键词数组导致正则报错 if (wordss.length === 0) return; // 构建初始正则:大小写不敏感,全局匹配 const regex = new RegExp(wordss.join('|'), 'ig'); const nodes = Array.from(el.childNodes); for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; if (node.nodeType === 3) { const nodeValue = node.nodeValue; const matches = []; let match; // 存储所有匹配项的位置和内容 while ((match = regex.exec(nodeValue.sanitiza())) !== null) { matches.push({ value: match[0], index: match.index }); // 修复正则lastIndex导致的无限循环问题 if (match[0].length === 0) regex.lastIndex++; } if (matches.length > 0) { let lastIndex = 0; // 遍历匹配结果,分割文本并插入高亮节点 matches.forEach(match => { // 插入匹配前的普通文本 if (lastIndex < match.index) { const textPart = nodeValue.substring(lastIndex, match.index); el.insertBefore(document.createTextNode(textPart), node); } // 创建高亮节点 const highLightNode = document.createElement("hightx"); highLightNode.style.border = '1px solid blue'; highLightNode.style.backgroundColor = '#ffea80'; highLightNode.appendChild(document.createTextNode(match.value)); el.insertBefore(highLightNode, node); // 更新最后位置 lastIndex = match.index + match.value.length; }); // 插入剩余的普通文本 if (lastIndex < nodeValue.length) { const textPart = nodeValue.substring(lastIndex); el.insertBefore(document.createTextNode(textPart), node); } // 移除原文本节点 el.removeChild(node); } } else { // 递归处理子元素 node.realcar(word); } } }
关键修改说明
- 数组隔离:不再直接引用原关键词数组,避免后续操作污染初始关键词列表。
- 精准匹配存储:记录每个匹配项的
index和value,确保高亮位置绝对准确,彻底解决错位问题。 - 简化逻辑:移除冗余的正则重构步骤,直接使用初始关键词正则进行匹配,逻辑更清晰。
- 修复正则循环问题:处理匹配空字符串的极端情况,避免正则
lastIndex导致的无限循环。
内容的提问来源于stack exchange,提问作者user3768564
相关产品推荐
相关产品推荐

