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

如何让onClick函数适配多个下拉菜单(无jQuery)

多下拉菜单优化实现(支持键盘操作)

完整代码示例

HTML

<div class="dropdown">
  <button onclick="openMenu(this)" class="drophover" aria-haspopup="true" aria-expanded="false">Other Sites</button>
  <div class="dropdown-content" role="menu">
    <a href="#" role="menuitem">Site Link 1</a>
    <a href="#" role="menuitem">Site Link 2</a>
  </div>
</div>
<div class="dropdown">
  <button onclick="openMenu(this)" class="drophover" aria-haspopup="true" aria-expanded="false">Personal</button>
  <div class="dropdown-content" role="menu" style="right: 0;">
    <a href="#" role="menuitem">Personal Link 1</a>
    <a href="#" role="menuitem">Personal Link 2</a>
  </div>
</div>

CSS

.dropdown-content {
  display: none;
}
.dropopen {
  display: block;
}
.drophover:focus {
  outline: 2px solid #005fcc; /* 自定义焦点样式,提升键盘可访问性 */
}
.dropdown-content a {
  display: block;
  padding: 8px;
  text-decoration: none;
}

JavaScript

function openMenu(button) {
  // 找到按钮的兄弟下拉内容元素
  const dropdownContent = button.nextElementSibling;
  // 切换显示状态
  dropdownContent.classList.toggle("dropopen");
  
  // 更新无障碍属性aria-expanded
  const isExpanded = dropdownContent.classList.contains("dropopen");
  button.setAttribute("aria-expanded", isExpanded);
}

// 监听ESC键,关闭所有下拉菜单
document.addEventListener("keydown", function(e) {
  if (e.key === "Escape") {
    const allDropdowns = document.querySelectorAll(".dropdown-content.dropopen");
    allDropdowns.forEach(dropdown => {
      dropdown.classList.remove("dropopen");
      // 找到对应的按钮,更新aria-expanded属性
      const button = dropdown.previousElementSibling;
      button.setAttribute("aria-expanded", false);
    });
  }
});

// 给所有下拉按钮添加键盘触发支持(回车/空格)
document.querySelectorAll(".drophover").forEach(button => {
  button.addEventListener("keydown", function(e) {
    if (e.key === "Enter" || e.key === " ") {
      e.preventDefault(); // 阻止默认行为(比如空格滚动页面)
      openMenu(this);
    }
  });
});

原理说明

1. 摆脱ID依赖,支持任意数量下拉菜单

  • 原来的代码硬编码ID,只能处理单个菜单。现在通过onclick="openMenu(this)"把触发点击的按钮元素传给函数,利用button.nextElementSibling直接找到相邻的下拉内容div——因为你的结构是按钮和下拉内容为兄弟元素,这个方法精准匹配。
  • 不管新增多少个结构相同的.dropdown容器,同一个openMenu函数都能处理,完全避免冗余代码。

2. 键盘操作支持细节

  • 按钮触发: 给所有下拉按钮添加keydown监听,当用户按下回车(Enter)或空格(Space)时触发菜单切换,符合Web无障碍标准,确保只用键盘也能操作菜单。
  • ESC关闭所有: 监听全局键盘事件,按下ESC键时,遍历所有打开的下拉菜单,移除.dropopen类关闭它们,同时更新按钮的aria-expanded属性(告诉屏幕阅读器菜单状态)。
  • 菜单内导航: 下拉内容里的链接默认支持Tab键切换焦点,只要菜单处于显示状态(display:block),就能正常用键盘导航,无需额外处理。

3. 无障碍优化(额外补充)

  • 添加aria-haspopup="true"、aria-expanded属性,以及role="menu"/role="menuitem",帮助屏幕阅读器识别菜单结构和状态,让菜单对残障用户更友好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 19:25:28