点击切换下拉菜单并隐藏其他所有下拉菜单的实现需求
我来帮你搞定这个多级菜单的交互需求——既要实现父菜单项点击切换下拉菜单的显示/隐藏,还要同时关闭其他已经展开的菜单。下面是完整的可运行方案:
多级折叠菜单实现方案
1. 修正后的完整HTML结构
先把你提供的不完整HTML补全,确保结构合法:
<nav> <ul> <li class="menu-item-has-children"> <a href="#">Parent item 1</a> <ul> <li><a href="#">Child item 1-1</a></li> <li><a href="#">Child item 1-2</a></li> </ul> </li> <li class="menu-item-has-children"> <a href="#">Parent item 2</a> <ul> <li><a href="#">Child item 2-1</a></li> <li><a href="#">Child item 2-2</a></li> </ul> </li> </ul> </nav>
2. 基础CSS样式
默认隐藏子菜单,给可展开的父项添加视觉标识(比如右侧箭头),同时通过active类控制子菜单的显示:
/* 重置列表默认样式 */ nav ul { list-style: none; padding: 0; margin: 0; background: #f5f5f5; } /* 菜单项基础样式 */ nav li { padding: 10px; border-bottom: 1px solid #ddd; } /* 父菜单项样式:添加箭头标识 */ .menu-item-has-children > a { position: relative; padding-right: 25px; display: block; cursor: pointer; } .menu-item-has-children > a::after { content: '▼'; position: absolute; right: 0; top: 50%; transform: translateY(-50%); font-size: 12px; } /* 激活状态下箭头朝上,提示菜单已展开 */ .menu-item-has-children.active > a::after { content: '▲'; } /* 默认隐藏子菜单 */ .menu-item-has-children ul { display: none; margin-top: 10px; background: #fff; padding-left: 20px; } /* 激活状态显示子菜单 */ .menu-item-has-children.active ul { display: block; }
3. JavaScript交互逻辑
实现点击父菜单项时的核心逻辑:切换自身下拉状态,同时关闭其他所有展开的菜单:
// 获取所有带子菜单的父项 const parentItems = document.querySelectorAll('.menu-item-has-children'); parentItems.forEach(item => { // 给父项的链接绑定点击事件 item.querySelector('a').addEventListener('click', function(e) { // 阻止默认跳转(因为href是#,不需要跳转到锚点) e.preventDefault(); // 切换当前父项的激活状态 const isActive = item.classList.toggle('active'); // 遍历所有父项,关闭当前项之外的其他展开菜单 parentItems.forEach(otherItem => { if (otherItem !== item) { otherItem.classList.remove('active'); } }); }); }); // 可选优化:点击子菜单项时不触发父项的折叠事件 document.querySelectorAll('.menu-item-has-children ul a').forEach(childLink => { childLink.addEventListener('click', function(e) { e.stopPropagation(); }); });
逻辑说明:
- 首先获取所有带
menu-item-has-children类的父菜单项 - 给每个父项的链接绑定点击事件,阻止默认跳转后切换自身的
active类(控制子菜单显示/隐藏) - 遍历所有父项,移除当前项之外的其他项的
active类,实现“关闭其他展开菜单”的效果 - 最后添加的子项点击阻止冒泡,避免点击子菜单时误触发父项的折叠逻辑
这个方案兼容性好,不需要依赖任何框架,纯原生JS就能实现需求,样式也可以根据你的设计需求自定义调整。
内容的提问来源于stack exchange,提问作者user2726041
相关产品推荐
相关产品推荐

