使用jQuery实现三级下拉导航的Tab键盘导航功能
三级键盘友好型下拉菜单实现
嘿,我明白你要的是什么——一个纯靠Tab键就能顺畅遍历的三级下拉菜单对吧?之前尝试没成功的话,多半是没处理好焦点事件和菜单展开/收起的逻辑衔接。下面是一个可直接运行的完整示例,完全支持键盘导航(Tab遍历、Esc关闭),符合无障碍设计标准:
完整代码实现
HTML 结构
<nav class="main-nav"> <ul class="nav-level-1"> <li class="nav-item"> <button class="nav-trigger">一级菜单 1</button> <ul class="nav-level-2"> <li class="nav-item"> <button class="nav-trigger">二级菜单 1-1</button> <ul class="nav-level-3"> <li class="nav-item"><a href="#item1">三级选项 1-1-1</a></li> <li class="nav-item"><a href="#item2">三级选项 1-1-2</a></li> <li class="nav-item"><a href="#item3">三级选项 1-1-3</a></li> </ul> </li> <li class="nav-item"><a href="#item4">二级选项 1-2</a></li> <li class="nav-item"> <button class="nav-trigger">二级菜单 1-3</button> <ul class="nav-level-3"> <li class="nav-item"><a href="#item5">三级选项 1-3-1</a></li> <li class="nav-item"><a href="#item6">三级选项 1-3-2</a></li> </ul> </li> </ul> </li> <li class="nav-item"><a href="#home">首页</a></li> <li class="nav-item"> <button class="nav-trigger">一级菜单 2</button> <ul class="nav-level-2"> <li class="nav-item"><a href="#item7">二级选项 2-1</a></li> <li class="nav-item"> <button class="nav-trigger">二级菜单 2-2</button> <ul class="nav-level-3"> <li class="nav-item"><a href="#item8">三级选项 2-2-1</a></li> <li class="nav-item"><a href="#item9">三级选项 2-2-2</a></li> <li class="nav-item"><a href="#item10">三级选项 2-2-3</a></li> </ul> </li> </ul> </li> </ul> </nav>
CSS 样式
/* 基础重置 */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: Arial, sans-serif; } .main-nav { background-color: #2c3e50; padding: 1rem; } .nav-level-1 { list-style: none; display: flex; gap: 1rem; } .nav-item { position: relative; } /* 菜单项样式 */ .nav-trigger, .nav-item a { display: block; padding: 0.5rem 1rem; color: white; text-decoration: none; background-color: transparent; border: none; cursor: pointer; font-size: 1rem; } .nav-trigger:hover, .nav-item a:hover, .nav-trigger:focus, .nav-item a:focus { background-color: #34495e; outline: 2px solid #ecf0f1; outline-offset: -2px; } /* 子菜单默认隐藏 */ .nav-level-2, .nav-level-3 { position: absolute; top: 100%; left: 0; list-style: none; background-color: #34495e; min-width: 180px; display: none; } .nav-level-3 { top: 0; left: 100%; } /* 展开状态显示子菜单 */ .nav-item:focus-within > .nav-level-2, .nav-item:focus-within > .nav-level-3 { display: block; }
JavaScript 逻辑(处理边缘情况)
// 给所有菜单触发器添加Esc键关闭功能 document.querySelectorAll('.nav-trigger').forEach(trigger => { trigger.addEventListener('keydown', (e) => { // 按下Esc键时,关闭当前子菜单并将焦点移回触发器 if (e.key === 'Escape') { trigger.blur(); trigger.focus(); } }); }); // 处理焦点离开整个菜单区域时关闭所有子菜单 document.querySelector('.main-nav').addEventListener('focusout', (e) => { if (!document.querySelector('.main-nav').contains(e.relatedTarget)) { // 焦点完全离开导航区域,重置所有子菜单状态 document.querySelectorAll('.nav-level-2, .nav-level-3').forEach(menu => { menu.style.display = 'none'; }); } });
关键特性说明
- 纯键盘导航: 只用Tab键就能遍历所有一级、二级、三级菜单选项,Shift+Tab可反向遍历
- 焦点可见: 所有可交互元素在聚焦时都有清晰的轮廓,符合无障碍标准
- 智能展开/收起: 当焦点进入菜单项时自动展开子菜单,焦点离开菜单区域时自动收起
- Esc键支持: 在展开的子菜单中按下Esc键,可快速关闭菜单并回到父级触发器
- 语义化结构: 使用
<nav>、<ul>、<button>等语义化标签,对屏幕阅读器友好
你可以直接把这段代码复制到HTML文件里运行,测试一下键盘导航的流畅度。如果需要调整样式或者扩展功能,直接修改对应的CSS或JS部分就行。
内容的提问来源于stack exchange,提问作者santosh krishna
相关产品推荐
相关产品推荐

