如何使用JavaScript实现嵌套ul li列表的搜索/筛选并显示下拉列表内容?
解决嵌套列表的搜索显示问题
嗨,我来帮你搞定这个搜索嵌套联系人的问题!你的代码现在没法搜到Billy和Bob,核心原因是当前搜索逻辑只检查了顶层<li>里的第一个链接文本,完全没考虑嵌套的子列表,而且就算子项匹配,父级<li>会因为自身文本不匹配被隐藏,导致子项也跟着看不见。
下面是修改后的完整代码,我会一步步解释关键改动:
<h2>My Phonebook</h2> <input type="text" id="myInput" onkeyup="search()" placeholder="Search for names.." title="Type in a name"> <ul id="myUL"> <li><a href="#">Adele</a></li> <li><a href="#">Agnes</a></li> <li><a href="#" onclick="show()">Click it Show hide peoples</a> <ul id="show_content"> <li><a href="#">Billy</a></li> <li><a href="#">Bob</a></li> </ul> </li> <li><a href="#">Calvin</a></li> <li><a href="#">Christina</a></li> <li><a href="#">Cindy</a></li> </ul> <script> function search() { var input, filter, allLis, links, hasMatch; input = document.getElementById("myInput"); filter = input.value.toUpperCase(); allLis = document.querySelectorAll("#myUL li"); // 获取所有层级的li,包括嵌套的 // 先默认隐藏所有li allLis.forEach(li => li.style.display = "none"); // 如果搜索框为空,恢复所有元素的默认显示 if (filter === "") { allLis.forEach(li => li.style.display = ""); // 同时把下拉列表恢复默认隐藏状态(可选,根据你的需求) document.getElementById("show_content").style.display = "none"; return; } allLis.forEach(li => { links = li.getElementsByTagName("a"); hasMatch = false; // 检查当前li下的所有链接文本 for (let j = 0; j < links.length; j++) { const txtValue = links[j].textContent || links[j].innerText; if (txtValue.toUpperCase().includes(filter)) { hasMatch = true; break; } } if (hasMatch) { // 显示当前匹配的li li.style.display = ""; // 自动展开当前li下的子列表(可选,如果你希望搜到子项时自动展开) const childUl = li.querySelector("ul"); if (childUl) childUl.style.display = ""; // 向上遍历所有父级li,确保它们都显示(不然父li隐藏的话子li也看不到) let currentParent = li.parentElement; while (currentParent && currentParent.tagName === "UL") { const parentLi = currentParent.parentElement; if (parentLi && parentLi.tagName === "LI") { parentLi.style.display = ""; } currentParent = currentParent.parentElement; } } }); } function show() { var a = document.getElementById("show_content"); a.style.display = a.style.display === "none" ? "" : "none"; } </script>
关键改动说明:
- 获取所有层级的li:用
document.querySelectorAll("#myUL li")代替原来的ul.getElementsByTagName("li"),这样能拿到嵌套在子ul里的Billy、Bob所在的li。 - 检查每个li下的所有链接:不再只看每个li里的第一个a标签,而是遍历当前li下的所有a标签,只要有一个匹配就算这个li符合条件。
- 显示父级元素:当子li匹配时,向上遍历所有父级的li并设置为显示,避免父li被隐藏导致子项不可见。
- 自动展开子列表(可选):如果搜索到子项,自动展开对应的下拉列表,不用手动点击"Click it Show hide peoples"。
- 空搜索恢复默认状态:搜索框清空时,把所有元素恢复到初始状态,包括隐藏下拉列表。
这样修改后,你搜索"Billy"或者"Bob"时,对应的子li会显示,父li也会保持可见,下拉列表也会自动展开(如果开启了可选功能),完美解决你的问题!
内容的提问来源于stack exchange,提问作者MaryAnn
相关产品推荐
相关产品推荐

