如何在嵌套列表中搜索条目并保留层级结构展示匹配结果
问题描述
希望通过页面顶部的输入框进行搜索,仅展示匹配搜索词的条目且保留原有的层级结构。当前编写的代码仅能正常展示父列表中的主列表条目,无法匹配子列表内的内容并保留层级。
当前运行效果

期望实现效果

现有代码
JS代码
$("#searchInputField").on("input", function() { var searchTerms = $(this).val().toLowerCase(); $(".nav_links li").each(function() { var hasMatch = searchTerms.length == 0 || $(this).text().toLowerCase().indexOf(searchTerms) > 0; var listItem = $(this); listItem.toggle(hasMatch); }); });
HTML代码
<script src="https://code.jquery.com/jquery-3.6.0.js"></script> <form action="#" novalidate="novalidate"> <input id="searchInputField" type="search" placeholder="Find" autocomplete="off"> </form> <ul class="nav_links"> <li> <span class="link_name navItem">Home</span> </li> <li> <div> <span class="link_name navItem">Costing Logistics</span> </div> <ul class="sub-menu"> <li><span class="navItem">HTML & CSS</span></li> <li><span class="navItem">JavaScript</span></li> <li><span class="navItem">PHP & MySQL</span></li> </ul> </li> </ul>
解决方案
原代码的问题是直接对所有li元素统一做显隐判断,没有考虑父子层级的联动逻辑:如果子列表项匹配搜索词,对应的父列表项也需要同步展示,同时子列表内不匹配的项要隐藏。此外原代码用indexOf(searchTerms) > 0判断匹配,会漏掉匹配文本开头的内容。
修改后的JS代码如下:
$("#searchInputField").on("input", function() { var searchTerms = $(this).val().toLowerCase().trim(); // 先重置所有元素为显示状态,避免上次筛选的结果影响当前判断 $(".nav_links li, .sub-menu").show(); if (searchTerms.length === 0) return; // 遍历一级父列表项 $(".nav_links > li").each(function() { const $parentLi = $(this); const parentText = $parentLi.children('.link_name, div').text().toLowerCase(); // 父项本身匹配搜索词,直接保留所有子项 if (parentText.includes(searchTerms)) return; // 父项不匹配时检查子项 let hasValidChild = false; $parentLi.find(".sub-menu > li").each(function() { const $childLi = $(this); const childMatch = $childLi.text().toLowerCase().includes(searchTerms); $childLi.toggle(childMatch); if (childMatch) hasValidChild = true; }); // 有匹配的子项就显示父项,否则隐藏整个父列表 $parentLi.toggle(hasValidChild); }); });
内容的提问来源于stack exchange,提问作者Abdelrahman Tamer
相关产品推荐
相关产品推荐

