You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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
  });
});

逻辑说明

  1. 绑定标签点击事件:因为Radio是隐藏的,用户实际操作的是关联的<label>,所以给每个标签绑定点击监听。
  2. 提前记录状态:在点击事件触发时,先获取Radio当前的选中状态(默认行为执行前的状态),避免后续判断出错。
  3. 分支处理:
    • 如果Radio已经选中,阻止默认的选中行为(避免重复触发选中),然后手动取消选中,关闭子菜单。
    • 如果Radio未选中,保留默认行为:Radio自动选中,同时同组其他Radio自动取消选中,实现互斥打开子菜单的效果。

注意事项

  • 所有需要互斥的Radio必须设置相同的name属性,这是Radio原生互斥特性的核心。
  • 确保每个Radio的id和对应<label>的for属性完全匹配,否则标签点击无法关联到Radio。

内容的提问来源于stack exchange,提问作者yjzhou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 14:10:13