JavaScript中.includes()方法在双列表选择场景下的异常问题问询
问题分析与代码修正
原始代码示例
HTML
<ul id="ul1"> <li class="td">dsfds</li> <li class="td">sdfdsf</li> <li class="td">sdfsfs</li> <li class="td">sfdsfds</li> <li class="td">sfdssfs</li> </ul> <ul id="ul2"> <li class="td">sfdss</li> <li class="td">sfsdfdsf</li> <li class="td">sfssfsf</li> <li class="td">sfsdsds</li> <li class="td">sdfsfds</li> </ul>
CSS
.selected{ background: rgba(0, 182, 94, 0.08); }
JavaScript
const ul1 = document.querySelector("#ul1"); const ul2 = document.querySelector("#ul2"); const tableRow1 = document.querySelectorAll("#ul1 .td"); const tableRow2 = document.querySelectorAll("#ul2 .td"); ul1.addEventListener('click', function (e) { if (e.target.classList.contains("td")) { e.target.classList.toggle("selected"); if (![...tableRow1].includes(document.querySelector(".selected"))) { console.log('true1'); } } }) ul2.addEventListener('click', function (e) { if (e.target.classList.contains("td")) { e.target.classList.toggle("selected"); if (![...tableRow2].includes(document.querySelector(".selected"))) { console.log('true2'); } } })
异常原因
核心问题出在document.querySelector(".selected")的使用逻辑上:
querySelector只会返回页面中第一个匹配选择器的元素,当ul1存在选中项时,它会直接获取ul1里的.selected元素,完全忽略ul2的选中状态。- 当前判断逻辑是“如果这个全局第一个选中元素不在ul2的元素集合里,就输出true2”,这和需求完全不符——需求是检查ul2内部是否没有任何选中项,而不是判断某个外部元素是否属于ul2。
举个具体场景:当ul1有选中项,同时ul2也有选中项时,document.querySelector(".selected")拿到的是ul1的元素,这个元素肯定不在tableRow2里,所以条件![...tableRow2].includes(...)会错误地返回true,导致不该输出true2的时候输出了。
修正方案
把判断逻辑改成直接检查目标列表内部是否存在选中项,替换掉原来的条件:
// 替换ul1里的判断逻辑 if (![...tableRow1].some(item => item.classList.contains("selected"))) { console.log('true1'); } // 替换ul2里的判断逻辑 if (![...tableRow2].some(item => item.classList.contains("selected"))) { console.log('true2'); }
或者更简洁的写法:
// ul1的判断逻辑 if (document.querySelectorAll("#ul1 .selected").length === 0) { console.log('true1'); } // ul2的判断逻辑 if (document.querySelectorAll("#ul2 .selected").length === 0) { console.log('true2'); }
内容的提问来源于stack exchange,提问作者Sayak Adhikary
相关产品推荐
相关产品推荐

