如何优化含隐藏字符的双字符串对比标记代码以减少冗余span标签
优化字符串差异标记的JS代码(减少冗余标签)
问题背景
对比两个字符串:一个是完整字符串A,另一个是部分字符被*隐藏的字符串B,需要用CSS标记出两者的差异部分。当前方案通过拆分字符串后逐个字符添加<span>,导致生成大量冗余标签,询问长字符串场景下的优化方法。
示例
- 完整字符串A:
123哈哈哈321哈哈哈123哈哈哈 - 隐藏字符串B:
123***321***123*** - 期望结果:
123<strong>哈哈哈</strong>321<strong>哈哈哈</strong>123<strong>哈哈哈</strong>
当前代码
let resultDom = document.querySelector('.resultDom') let aStringWithSplit = [1, 2, 3, '哈', '哈', '哈', 3, 2, 1, '哈', '哈', '哈', 1, 2, 3, '哈', '哈', '哈'] let bStringWithSplit = [1, 2, 3, '*', '*', '*', 3, 2, 1, '*', '*', '*', 1, 2, 3, '*', '*', '*'] let getIndexWithHidden = [] let result = '' bStringWithSplit.forEach((item, index) => { if (item === '*') { getIndexWithHidden.push(index) } }) aStringWithSplit.forEach((item, index) => { if (getIndexWithHidden.indexOf(index)!== -1) { result += `<span style='color: red;'>${item}</span>` } else { result += `<span>${item}</span>` } }) resultDom.innerHTML = result
<div class='resultDom'></div>
优化方案
核心思路是连续相同状态的字符批量处理,而非逐个添加标签,大幅减少DOM元素数量。
实现代码
const resultDom = document.querySelector('.resultDom'); const fullStr = '123哈哈哈321哈哈哈123哈哈哈'; const hiddenStr = '123***321***123***'; let result = ''; let currentSegment = ''; let isHighlight = false; // 一次遍历完成片段合并与标签生成 for (let i = 0; i < fullStr.length; i++) { const isHidden = hiddenStr[i] === '*'; // 当前字符状态与之前一致时,追加到当前片段 if (isHidden === isHighlight) { currentSegment += fullStr[i]; } else { // 状态切换时,先处理完上一个片段 result += isHighlight ? `<span style="color: red;">${currentSegment}</span>` : currentSegment; // 重置片段与状态 currentSegment = fullStr[i]; isHighlight = isHidden; } } // 处理最后一段未完成的片段 result += isHighlight ? `<span style="color: red;">${currentSegment}</span>` : currentSegment; resultDom.innerHTML = result;
优化点说明
- 减少DOM节点:连续的普通/高亮字符会被合并成单个标签(或直接作为文本),不再每个字符单独生成
<span>,长字符串场景下DOM节点数量大幅降低。 - 简化逻辑:无需提前收集所有
*的索引,一次遍历完成处理,减少内存占用与遍历次数。 - 性能提升:批量处理避免了频繁字符串拼接的额外开销,执行效率更高。
可选扩展优化
如果需要复用样式,建议把内联样式替换为CSS类,更符合代码规范:
.highlight-text { color: red; }
对应JS代码修改为:
result += isHighlight ? `<span class="highlight-text">${currentSegment}</span>` : currentSegment;
内容的提问来源于stack exchange,提问作者howhow
相关产品推荐
相关产品推荐

