HTML侧边栏搜索栏优化:搜索时自动展开下拉或仅显示匹配结果
问题原因
现有代码的缺陷本质是只控制了<li>列表项的显示状态,忽略了侧边栏折叠的实现逻辑:你的菜单是通过复选框:checked状态绑定CSS规则,给折叠容器设置max-height: 0+overflow: hidden实现隐藏的。就算内部<li>设置为可见,被高度为0的父容器裁剪后依然无法显示。
另外原代码里存在冗余变量closestClass = ul.closest('.parent'),整个DOM结构中不存在.parent类,该变量无实际作用。
额外提示:你提供的CSS代码中
@keyframes move规则末尾多了一个多余的},会导致后续弹窗相关样式解析失效,建议删除。
修复实现(方案二:搜索时自动展开含匹配项的菜单)
该方案对原有交互侵入最小,用户清空搜索框后会自动收回搜索时展开的菜单,保留用户手动展开/折叠的状态不受影响,直接替换原有searchSite函数即可:
function searchSite() { const input = document.getElementById('searchbar'); const filter = input.value.trim().toUpperCase(); const sidebar = document.getElementById("Sidebar"); const allLi = sidebar.getElementsByTagName('li'); const allMenuTriggers = sidebar.querySelectorAll('.button, .subbutton'); // 搜索框为空时恢复初始状态 if (!filter) { // 恢复所有列表项显示 for (let i = 0; i < allLi.length; i++) { allLi[i].style.display = ""; } // 收回搜索触发的自动展开,不影响用户手动展开的菜单 allMenuTriggers.forEach(trigger => { if (trigger.dataset.searchExpanded) { trigger.checked = false; delete trigger.dataset.searchExpanded; } }); return; } // 遍历所有链接项匹配搜索词 for (let i = 0; i < allLi.length; i++) { const link = allLi[i].getElementsByTagName("a")[0]; if (!link) continue; const text = (link.textContent || link.innerText).toUpperCase(); if (text.indexOf(filter) > -1) { allLi[i].style.display = ""; // 向上查找所有父级折叠容器,自动展开 let parentContainer = link.closest('.content, .subcontent'); while (parentContainer) { const trigger = parentContainer.previousElementSibling; if (trigger?.classList.contains('button') || trigger?.classList.contains('subbutton')) { if (!trigger.checked) { trigger.checked = true; // 标记为搜索触发的展开,清空时可还原 trigger.dataset.searchExpanded = "true"; } } parentContainer = parentContainer.parentElement.closest('.content, .subcontent'); } } else { allLi[i].style.display = "none"; } } }
可选方案(方案一:仅展示匹配结果,隐藏菜单头部)
如果需要实现搜索时完全隐藏菜单层级、只保留匹配的链接项,只需要在上述逻辑基础上,增加对.header、.subheader元素的显示控制即可:匹配到内容时隐藏所有菜单头部,无匹配内容的容器全部设为隐藏,清空搜索时恢复所有元素的默认显示状态。
内容的提问来源于stack exchange,提问作者user540393
相关产品推荐
相关产品推荐

