如何用JavaScript实现单选按钮控制下拉子菜单的开合与取消选中
解决Radio按钮下拉菜单的选中取消问题(保持互斥+可关闭)
核心思路是在用户点击菜单标签时,提前判断对应Radio的选中状态,再决定是保持选中还是取消,同时保留Radio的原生互斥特性。
完整实现代码
HTML结构
<div class="dropdown-menu"> <div class="menu-item"> <label for="menu1">菜单1</label> <input type="radio" name="dropdown-group" id="menu1" hidden> <div class="submenu"> <a href="#">子选项1-1</a> <a href="#">子选项1-2</a> </div> </div> <div class="menu-item"> <label for="menu2">菜单2</label> <input type="radio" name="dropdown-group" id="menu2" hidden> <div class="submenu"> <a href="#">子选项2-1</a> <a href="#">子选项2-2</a> </div> </div> <div class="menu-item"> <label for="menu3">菜单3</label> <input type="radio" name="dropdown-group" id="menu3" hidden> <div class="submenu"> <a href="#">子选项3-1</a> <a href="#">子选项3-2</a> </div> </div> </div>
CSS样式
/* 基础菜单样式 */ .menu-item label { cursor: pointer; display: block; padding: 10px 15px; background-color: #f5f5f5; border-bottom: 1px solid #eee; } /* 子菜单默认隐藏 */ .submenu { display: none; padding: 8px 0; margin-left: 20px; border-left: 2px solid #ddd; } .submenu a { display: block; padding: 6px 15px; text-decoration: none; color: #333; } /* Radio选中时显示对应子菜单 */ input[type="radio"]:checked + .submenu { display: block; }
JavaScript逻辑
// 获取同一组的所有Radio按钮 const radioGroup = document.querySelectorAll('input[name="dropdown-group"]'); radioGroup.forEach(radio => { // 找到对应点击的标签元素 const triggerLabel = document.querySelector(`label[for="${radio.id}"]`); triggerLabel.addEventListener('click', (e) => { // 点击瞬间先记录当前Radio的选中状态 const wasPreChecked = radio.checked; // 如果已经选中,阻止默认选中行为,直接取消选中 if (wasPreChecked) { e.preventDefault(); radio.checked = false; } // 未选中的情况,让Radio默认行为执行:自动选中并取消同组其他Radio }); });
逻辑说明
- 绑定标签点击事件:因为Radio是隐藏的,用户实际操作的是关联的
<label>,所以给每个标签绑定点击监听。 - 提前记录状态:在点击事件触发时,先获取Radio当前的选中状态(默认行为执行前的状态),避免后续判断出错。
- 分支处理:
- 如果Radio已经选中,阻止默认的选中行为(避免重复触发选中),然后手动取消选中,关闭子菜单。
- 如果Radio未选中,保留默认行为:Radio自动选中,同时同组其他Radio自动取消选中,实现互斥打开子菜单的效果。
注意事项
- 所有需要互斥的Radio必须设置相同的name属性,这是Radio原生互斥特性的核心。
- 确保每个Radio的
id和对应<label>的for属性完全匹配,否则标签点击无法关联到Radio。
内容的提问来源于stack exchange,提问作者yjzhou
相关产品推荐
相关产品推荐

