如何实现相同类多级列表下拉菜单点击单个展开其余自动关闭
问题原因
- HTML规范中id属性必须全局唯一,你给多个
li和下拉容器都设置了相同的arrowSub、indiSetid,属于不规范写法,会导致选择器匹配异常。 - 现有的
openSets函数逻辑是遍历所有下拉容器统一设置状态,所以点击任意箭头都会触发所有下拉框同时展开/收起。
修复步骤
1. 修改HTML代码
把重复的id替换为class,修改后代码如下:
<ul> <li> <p><i class="fas fa-folder"></i> ERGEBNIS</p> <ul> <li> <p class="left"><i class="fas fa-folder"></i> EQA-ERGEBNIS1.csv <i class="fas fa-arrow-to-bottom"></i> <i class="fas fa-chart-bar"></i></p> </li> </ul> </li> <li> <p><i class="fas fa-folder"></i> Testdaten-Sets <i class="fal fa-chevron-down" id="arrow2" onclick="showSets()"></i></p> <div class="sets" id="sets"> <ul> <li class="arrowSub"> <p><i class="fas fa-folder"></i> Testdaten-Set 1 <i class="fal fa-chevron-down"></i></p> <div class="indiSet"> <p><i class="fal fa-folder"></i> 1_R1.fastq</p> <p><i class="fal fa-folder"></i> 1_R2.fastq</p> <p><i class="fal fa-folder"></i> Koordinaten.bed</p> <p><i class="fal fa-folder"></i> Ground_Truth.vcf</p> </div> </li> <li class="arrowSub"> <p><i class="fas fa-folder"></i> Testdaten-Set 2 <i class="fal fa-chevron-down"></i></p> <div class="indiSet"> <p><i class="fal fa-folder"></i> 2_R1.fastq</p> <p><i class="fal fa-folder"></i> 2_R2.fastq</p> <p><i class="fal fa-folder"></i> Koordinaten.bed</p> <p><i class="fal fa-folder"></i> Ground_Truth.vcf</p> </div> </li> <li class="arrowSub"> <p><i class="fas fa-folder"></i> Testdaten-Set 3 <i class="fal fa-chevron-down"></i></p> <div class="indiSet"> <p><i class="fal fa-folder"></i> 3_R1.fastq</p> <p><i class="fal fa-folder"></i> 3_R2.fastq</p> <p><i class="fal fa-folder"></i> Koordinaten.bed</p> <p><i class="fal fa-folder"></i> Ground_Truth.vcf</p> </div> </li> </ul> </div> </li> </ul>
2. 补充CSS(默认隐藏下拉框,可加过渡效果)
.indiSet { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; } /* 可选:添加箭头旋转动画 */ .arrowSub .fa-chevron-down { transition: transform 0.3s ease; } .arrowSub.active .fa-chevron-down { transform: rotate(180deg); }
3. 修改JS代码
const arrowSubList = document.querySelectorAll(".arrowSub"); function openSets(e) { // 获取当前点击的父容器 const currentItem = e.currentTarget; // 获取当前容器对应的下拉框 const currentDrop = currentItem.querySelector(".indiSet"); const isOpened = !!currentDrop.style.maxHeight; // 先关闭所有下拉框,移除所有激活状态 arrowSubList.forEach(item => { const drop = item.querySelector(".indiSet"); drop.style.maxHeight = null; item.classList.remove('active'); }); // 如果当前点击的下拉框之前是关闭状态,就展开它 if (!isOpened) { currentDrop.style.maxHeight = currentDrop.scrollHeight + 5 + "px"; currentItem.classList.add('active'); } } arrowSubList.forEach(item => { item.addEventListener('click', openSets); });
修改后点击任意下拉箭头,只会展开当前对应的下拉框,同时自动关闭其他已经展开的下拉框,符合预期效果。
内容的提问来源于stack exchange,提问作者Killian Pierce
相关产品推荐
相关产品推荐

