JS脚本同索引Span高亮异常:空Span对应项未显示指定颜色
对应索引Span高亮逻辑问题:空对应项时未显示指定颜色
我想要实现两个容器中对应索引的<span>元素高亮,需求是:
- 基础功能:悬停一个span时,对应索引的另一个span也高亮(黄色)
- 特殊规则:当两个对应span中有一个为空时,非空的那个span需要用绿色高亮(
highlight-empty类)
但测试时发现,悬停text2中第三个标注为add => empty span on the other side的span时,它仍然显示黄色,没有变成绿色。以下是我的代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="styles.css"> <title>Textes en Parallèle</title> <style> body { display: flex; } .text-container { flex: 1; margin: 10px; border: 1px solid #ccc; padding: 10px; overflow-y: scroll; max-height: 300px; } .highlight { background-color: yellow; } .highlight-empty { background-color: #8eff8e; /* 高亮用绿色 */ } </style> </head> <body> <div class="text-container" id="text1"> <!-- 文本第一版 --> <span>span1.</span> common text <span>span 2.</span> <span></span> </div> <div class="text-container" id="text2"> <!-- 文本第二版 --> <span>corresponding span 1.</span> common text <span>corresp span 2</span> <span>add => empty span on the other side</span> </div> <script> document.addEventListener('DOMContentLoaded', function () { const textContainers1 = document.getElementById('text1').querySelectorAll('span'); const textContainers2 = document.getElementById('text2').querySelectorAll('span'); function addHighlight(index) { textContainers1[index].classList.add('highlight'); textContainers2[index].classList.add('highlight'); } function removeHighlight(index) { textContainers1[index].classList.remove('highlight'); textContainers2[index].classList.remove('highlight'); } textContainers1.forEach((paragraph1, index) => { paragraph1.addEventListener('mouseover', () => { if (textContainers2[index].innerHTML.trim() === '') { textContainers2[index].classList.add('highlight-empty'); } addHighlight(index); }); paragraph1.addEventListener('mouseout', () => { removeHighlight(index); textContainers2[index].classList.remove('highlight-empty'); }); }); textContainers2.forEach((paragraph2, index) => { paragraph2.addEventListener('mouseover', () => { if (textContainers1[index].innerHTML.trim() === '') { textContainers1[index].classList.add('highlight-empty'); } addHighlight(index); }); paragraph2.addEventListener('mouseout', () => { removeHighlight(index); textContainers1[index].classList.remove('highlight-empty'); }); }); }); </script> </body> </html>
问题出在哪?
- 逻辑搞反了:你现在是给空的那个span加绿色高亮,但需求是当对应项为空时,给有内容的那个span(不管是当前悬停的还是对应的)加绿色。比如悬停text2的第三个span时,你判断text1的span是空的,然后给text1的空span加了绿色,而不是给当前悬停的text2的span加。
- 类叠加导致样式冲突:就算逻辑对了,你先加绿色类,然后调用
addHighlight又加了黄色类,两个类都在同一个元素上,CSS优先级相同的情况下,后面定义的样式会覆盖前面的,但你要的是只显示绿色,所以不能同时加两个类。
修复后的代码
调整逻辑,根据对应项是否为空,决定给当前悬停的span和对应span添加哪个高亮类,避免同时叠加两个类:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Textes en Parallèle</title> <style> body { display: flex; } .text-container { flex: 1; margin: 10px; border: 1px solid #ccc; padding: 10px; overflow-y: scroll; max-height: 300px; } .highlight { background-color: yellow; } .highlight-empty { background-color: #8eff8e; /* 高亮用绿色 */ } </style> </head> <body> <div class="text-container" id="text1"> <!-- 文本第一版 --> <span>span1.</span> common text <span>span 2.</span> <span></span> </div> <div class="text-container" id="text2"> <!-- 文本第二版 --> <span>corresponding span 1.</span> common text <span>corresp span 2</span> <span>add => empty span on the other side</span> </div> <script> document.addEventListener('DOMContentLoaded', function () { const textContainers1 = document.getElementById('text1').querySelectorAll('span'); const textContainers2 = document.getElementById('text2').querySelectorAll('span'); // 移除所有高亮类的通用方法 function removeAllHighlights(index) { textContainers1[index].classList.remove('highlight', 'highlight-empty'); textContainers2[index].classList.remove('highlight', 'highlight-empty'); } // 处理text1的span悬停 textContainers1.forEach((span1, index) => { span1.addEventListener('mouseover', () => { const span2 = textContainers2[index]; const span1IsEmpty = span1.innerHTML.trim() === ''; const span2IsEmpty = span2.innerHTML.trim() === ''; removeAllHighlights(index); if (span2IsEmpty) { // 对应span2为空,给当前span1加绿色高亮 span1.classList.add('highlight-empty'); } else if (span1IsEmpty) { // 当前span1为空,给对应span2加绿色高亮 span2.classList.add('highlight-empty'); } else { // 都不为空,正常黄色高亮 span1.classList.add('highlight'); span2.classList.add('highlight'); } }); span1.addEventListener('mouseout', () => { removeAllHighlights(index); }); }); // 处理text2的span悬停 textContainers2.forEach((span2, index) => { span2.addEventListener('mouseover', () => { const span1 = textContainers1[index]; const span1IsEmpty = span1.innerHTML.trim() === ''; const span2IsEmpty = span2.innerHTML.trim() === ''; removeAllHighlights(index); if (span1IsEmpty) { // 对应span1为空,给当前span2加绿色高亮 span2.classList.add('highlight-empty'); } else if (span2IsEmpty) { // 当前span2为空,给对应span1加绿色高亮 span1.classList.add('highlight-empty'); } else { // 都不为空,正常黄色高亮 span1.classList.add('highlight'); span2.classList.add('highlight'); } }); span2.addEventListener('mouseout', () => { removeAllHighlights(index); }); }); }); </script> </body> </html>
关键调整点
- 新增
removeAllHighlights方法,确保每次悬停前清除所有高亮类,避免类叠加 - 悬停时先判断对应项是否为空,再决定给哪个元素添加哪种高亮类,不再同时叠加
highlight和highlight-empty - 调整逻辑方向:当对应项为空时,给当前悬停的非空span(或对应的非空span)添加绿色高亮类,完全符合需求
内容的提问来源于stack exchange,提问作者Clara
相关产品推荐
相关产品推荐

