移动端折叠菜单优化需求:展开新菜单时自动折叠其他菜单
移动端折叠菜单优化:展开单个菜单时自动折叠其他菜单
问题说明
已实现移动端折叠菜单,支持点击展开/收起子菜单,但存在交互缺陷:展开新菜单时,其他已展开的菜单不会自动折叠。需求是点击展开任意菜单后,其余所有菜单自动恢复折叠状态。
当前状态示例
----- ----- ▼ (折叠) ----- ▼ (折叠) ----- ▲ (展开) |---- |---- |---- ----- ▼ (折叠) ----- ▲ (展开) |---- |---- |----
期望状态示例
----- ----- ▼ (折叠) ----- ▼ (折叠) ----- ▲ (展开) |---- |---- |---- ----- ▼ (折叠) ----- ▼ (折叠)
当前实现代码
JavaScript
let acc = document.getElementsByClassName("mobile-unfold"); let i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function() { this.classList.toggle("active"); let panel = this.nextElementSibling; if (panel.style.maxHeight) { panel.style.maxHeight = null; } else { panel.style.maxHeight = panel.scrollHeight + "px"; } }); }
CSS
.corp-menu-small { display: flex; opacity: 100%; flex-direction: column; align-items: flex-start; margin: 0 auto; transition: opacity 0.4s, display 0.4s; top: 20%; left: 33%; width: 35%; position: absolute; padding-top: 15px; } .nav-mobile-overlay { display: flex; } :where(.mobile-unfold:nth-child(2n))::after { content: url("../../media/svg/arrow-mobile.svg"); filter: brightness(0) invert(1); margin-left: 10px; } .active::after { content: url("../../media/svg/arrow-mobile.svg"); transform: rotate(180deg); filter: brightness(0) invert(1); } .links-unfold-wrapper { overflow: hidden; background-color: transparent; max-height: 0; transition: max-height 0.2s ease-out; display: flex; flex-direction: column; margin-left: 8px; } .links-unfold { margin-left: 8px; font-family: 'FiraSansLight'; font-size: 16px !important; font-weight: normal; color: white; }
HTML
<div class="corp-menu-small"> <a class="menu nav-mobile-overlay" href="#">MENU 1</a> <a class="menu nav-mobile-overlay mobile-unfold" href="#"> MENU 2 <div class="links-unfold-wrapper"> <a class="menu links-unfold" href="#">SubMenu 1</a> <a class="menu links-unfold" href="#">SubMenu 2</a> <a class="menu links-unfold" href="#">SubMenu 3</a> </div> </a> <a class="menu nav-mobile-overlay mobile-unfold" href="# ">MENU 3 <div class="links-unfold-wrapper"> <a class="menu links-unfold" href="#">SubMenu 1</a> <a class="menu links-unfold" href="#">SubMenu 2</a> <a class="menu links-unfold" href="#">SubMenu 3</a> <a class="menu links-unfold" href="#">SubMenu 4</a> </div> </a> <a class="menu nav-mobile-overlay mobile-unfold" href="#">MENU 4 <div class="links-unfold-wrapper"> <a class="menu links-unfold" href="#">SubMenu 1</a> <a class="menu links-unfold" href="#">SubMenu 2</a> <a class="menu links-unfold" href="#">SubMenu 3</a> </div> </a> </div>
解决方案
修改JavaScript代码,在点击当前菜单时先折叠所有其他菜单,再处理当前菜单的展开/收起逻辑:
let acc = document.getElementsByClassName("mobile-unfold"); for (let i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function() { // 遍历所有菜单,折叠当前菜单以外的所有菜单 for (let j = 0; j < acc.length; j++) { if (acc[j] !== this) { acc[j].classList.remove("active"); const panel = acc[j].querySelector('.links-unfold-wrapper'); panel.style.maxHeight = null; } } // 处理当前菜单的展开/收起 this.classList.toggle("active"); const panel = this.querySelector('.links-unfold-wrapper'); if (panel.style.maxHeight) { panel.style.maxHeight = null; } else { panel.style.maxHeight = panel.scrollHeight + "px"; } }); }
关键改动说明
- 修正子菜单容器获取方式:原代码用
nextElementSibling错误,因为子菜单是当前a标签的子元素,改用querySelector('.links-unfold-wrapper')精准定位。 - 新增批量折叠逻辑:点击菜单时,先遍历所有菜单,移除其他菜单的
active类并设置子菜单maxHeight为null,实现自动折叠。 - 保留当前菜单交互:保留
toggle逻辑,支持点击同一菜单时收起自身。
内容的提问来源于stack exchange,提问作者user23485998
相关产品推荐
相关产品推荐

