如何让PrimeReact弹出菜单支持键盘Tab导航与aria-labels功能?
问题描述
按下按钮的Enter键打开弹出菜单后,无法使用Tab键遍历菜单选项,期望实现Tab键遍历并选择合适选项。
现有代码
import { Button } from 'primereact/button'; import { Menu } from 'primereact/menu'; function Header() { const [menu, setMenu] = useState(''); const testModelItems = [{label: 'Menu', items: [{label: 'Main 1'}, {label: 'Option 2'}]}]; return ( <div className={'menu-button-div'}> <Menu model={testModelItems} popup ref={(e) => setMenu(e)} id={'menu'} aria-labelledby={'menu-dropdown'}/> <Button aria-expanded={false} aria-labelledby={'menu-dropdown'} aria-controls={'menu'} aria-haspopup label={'Main Menu'} onClick={(e) => menu.toggle(e)}/> </div> ) }
解决方案
关键调整点
- 绑定菜单展开状态到
aria-expanded,符合无障碍交互标准 - 菜单弹出后手动管理菜单项的
tabindex,允许Tab键聚焦 - 自动聚焦首个菜单项,确保键盘交互的连贯性
修改后代码
import { useState } from 'react'; import { Button } from 'primereact/button'; import { Menu } from 'primereact/menu'; function Header() { const [menu, setMenu] = useState(null); const [menuVisible, setMenuVisible] = useState(false); const testModelItems = [{label: 'Menu', items: [{label: 'Main 1'}, {label: 'Option 2'}]}]; const handleMenuShow = () => { setMenuVisible(true); // 菜单弹出后,设置所有菜单项可被Tab聚焦,并自动聚焦首个选项 setTimeout(() => { const menuItems = document.querySelectorAll('#menu .p-menuitem-link'); if (menuItems.length > 0) { menuItems.forEach(item => item.setAttribute('tabindex', '0')); menuItems[0].focus(); } }, 0); }; const handleMenuHide = () => { setMenuVisible(false); // 菜单关闭后恢复菜单项的tabindex,避免干扰其他交互 const menuItems = document.querySelectorAll('#menu .p-menuitem-link'); menuItems.forEach(item => item.setAttribute('tabindex', '-1')); }; return ( <div className={'menu-button-div'}> <Menu model={testModelItems} popup ref={(e) => setMenu(e)} id={'menu'} aria-labelledby={'menu-dropdown'} onShow={handleMenuShow} onHide={handleMenuHide} /> <Button aria-expanded={menuVisible} aria-labelledby={'menu-dropdown'} aria-controls={'menu'} aria-haspopup="true" label={'Main Menu'} onClick={(e) => menu.toggle(e)} /> </div> ) }
补充说明
通用的无障碍菜单交互规范中,弹出菜单默认用上下箭头键遍历选项,Tab键用于退出菜单回到触发按钮。如果坚持使用Tab遍历,上述修改可实现需求,但建议优先遵循标准交互模式,提升用户体验一致性。
内容的提问来源于stack exchange,提问作者Grammin
相关产品推荐
相关产品推荐

