如何让Bootstrap 5菜单的上下箭头键实现循环导航
Bootstrap 5 下拉菜单实现循环键盘导航
默认情况下,Bootstrap 5 的下拉菜单在第一个菜单项按上箭头、最后一个菜单项按下箭头时无响应。需要实现类似 Windows 桌面应用菜单的循环导航效果:第一个项按上箭头跳转至最后一项,最后一项按下箭头跳转至第一项。
复现代码
<div class="btn-group"> <button type="button" class="btn btn-danger dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false"> Action </button> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="#"><u>A</u>ction</a></li> <li><a class="dropdown-item" href="#">A<u>n</u>other action</a></li> <li><a class="dropdown-item" href="#"><u>S</u>omething else here</a></li> <li><hr class="dropdown-divider"></li> <li><a class="dropdown-item" href="#">S<u>e</u>parated link</a></li> </ul> </div>
实现方案
通过监听键盘事件,自定义上下箭头的导航逻辑,跳过不可交互的分隔线,实现循环聚焦:
- 全局监听键盘按下事件,仅处理上下箭头按键
- 确认当前激活元素是下拉菜单项
- 获取当前菜单中所有可交互的菜单项,计算目标聚焦位置
- 阻止默认行为,聚焦到目标项
代码实现
document.addEventListener('keydown', function(e) { if (!['ArrowUp', 'ArrowDown'].includes(e.key)) return; const activeItem = document.activeElement; if (!activeItem?.classList.contains('dropdown-item')) return; const dropdownMenu = activeItem.closest('.dropdown-menu'); const items = Array.from(dropdownMenu.querySelectorAll('.dropdown-item')); const currentIndex = items.indexOf(activeItem); let targetIndex; if (e.key === 'ArrowUp') { targetIndex = currentIndex === 0 ? items.length - 1 : currentIndex - 1; } else { targetIndex = currentIndex === items.length - 1 ? 0 : currentIndex + 1; } e.preventDefault(); items[targetIndex].focus(); });
说明
- 代码对所有Bootstrap下拉菜单生效,无需单独绑定
- 自动忽略下拉分隔线,只处理可交互的菜单项
- 保留Bootstrap原有键盘交互逻辑(如回车触发点击、ESC关闭菜单等)
内容的提问来源于stack exchange,提问作者Andrus
相关产品推荐
相关产品推荐

