
本文讲解如何修正多组下拉菜单点击时全部展开的问题,通过为每个菜单绑定独立事件、使用 data-* 属性追踪状态,并配合 JavaScript 动态控制显隐,确保每次仅一个菜单展开。
本文讲解如何修正多组下拉菜单点击时全部展开的问题,通过为每个菜单绑定独立事件、使用 `data-*` 属性追踪状态,并配合 javascript 动态控制显隐,确保每次仅一个菜单展开。
在原代码中,所有下拉菜单均使用相同 ID(如 id="myDropdown")和全局 getElementById 调用,导致 myFunction() 每次只操作第一个匹配元素;而关闭逻辑虽遍历所有 .hidden-content,却未区分「当前点击项」与「其他已开项」——最关键的是:点击一个按钮时,应关闭其他已展开的菜单,再切换自身状态(即“独占展开”)。
以下是优化后的专业实现方案,兼顾语义性、可维护性与行为一致性:
✅ 正确结构:每个菜单自成独立模块
避免重复 ID,改用 class + DOM 遍历定位兄弟元素:
<div class="dropdown-group">
<button class="dropbtn">标题一</button>
<div class="dropdown-menu">
<div class="article-list">
<p>内容1</p>
<p>内容2</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/js/8057" title="jQuery竖直手风琴折叠菜单代码"><img
src="https://img.php.cn/upload/jscode/000/000/006/170918821546569.jpg" alt="jQuery竖直手风琴折叠菜单代码" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/js/8057" title="jQuery竖直手风琴折叠菜单代码" class="overflowclass">jQuery竖直手风琴折叠菜单代码</a>
<p class="overflowclass">jQuery竖直手风琴折叠菜单代码是一款实用的手风琴折叠菜单代码,点击可以收缩展开子菜单。</p>
</div>
<a rel="nofollow" href="/xiazai/js/8057" title="jQuery竖直手风琴折叠菜单代码" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
</div>
</div>
</div>
<div class="dropdown-group">
<button class="dropbtn">标题二</button>
<div class="dropdown-menu">
<div class="article-list">
<p>内容A</p>
<p>内容B</p>
</div>
</div>
</div>
✅ CSS:精简并复用样式
移除对 #myDropdown 的依赖,改用类名控制:
.dropbtn {
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
width: 100%;
font-family: 'Turret Road';
font-size: 35px;
font-weight: 600;
color: var(--default5);
text-align: center;
border-radius: 15px;
background-image: linear-gradient(var(--defaultAccent1), var(--default3Muted));
box-shadow: var(--default1) 3px 3px 3px 3px;
}
.dropbtn:hover, .dropbtn:focus {
background-image: linear-gradient(var(--defaultAccent1), var(--default1));
}
.dropdown-group {
position: relative;
margin-bottom: 1rem;
}
.dropdown-menu {
display: none;
position: relative;
width: 100%;
background-color: var(--default3Muted);
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
border-radius: 15px;
margin-top: 8px;
}
.dropdown-menu.show {
display: block;
}
.dropdown-menu a {
color: var(--default1);
padding: 12px 16px;
text-decoration: none;
display: block;
}
✅ JavaScript:精准控制单菜单展开(推荐方案)
使用事件委托 + 兄弟节点查找,确保每次仅一个 .dropdown-menu 显示:
// 点击按钮时:关闭所有菜单 → 展开当前关联菜单
document.addEventListener('click', function(e) {
if (e.target.classList.contains('dropbtn')) {
const group = e.target.closest('.dropdown-group');
const targetMenu = group?.querySelector('.dropdown-menu');
// 关闭所有已展开的菜单
document.querySelectorAll('.dropdown-menu.show').forEach(el => {
el.classList.remove('show');
});
// 展开当前菜单(若尚未展开)
if (targetMenu && !targetMenu.classList.contains('show')) {
targetMenu.classList.add('show');
}
}
});
// 点击页面其他区域时关闭所有菜单(可选增强体验)
document.addEventListener('click', function(e) {
if (!e.target.closest('.dropdown-group')) {
document.querySelectorAll('.dropdown-menu.show').forEach(el => {
el.classList.remove('show');
});
}
});
⚠️ 注意事项
- 禁止重复 ID:HTML 中 id 必须唯一,否则 getElementById 行为不可预测;
- 避免内联 JS 绑定:如 onclick="myFunction()",易造成维护困难且无法动态注册;
- .closest() 是关键:它从点击目标向上查找最近的 .dropdown-group 容器,从而精准定位对应菜单;
- 若需支持键盘访问(如回车/空格展开),建议补充 keydown 事件监听,提升无障碍体验。
该方案彻底解耦各菜单实例,无需 data-show 或手动管理样式内联,完全基于 CSS 类控制状态,简洁、健壮、符合现代前端实践。










