accesskey 不能与前端路由结合用于页面切换,它仅触发 focus() 而非跳转,不改变 URL 或同步路由状态;强行混用会导致快捷键失效、行为不可预测、可访问性下降。

accesskey 和前端路由不能也不该“结合”用于页面切换——它不触发跳转,不改变 URL,也不参与路由逻辑。强行混用只会让快捷键失效、行为不可预测、可访问性下降。
accesskey 本质是聚焦,不是导航
它唯一规范行为是调用 element.focus(),哪怕你给一个 <a href="/about"> 加了 accesskey="a",按 Alt+A 也只把焦点移到链接上,不会触发跳转。浏览器不会自动调用 .click() 或 history.pushState()。这和前端路由要的“URL 变、视图换、状态同步”完全不在一个层面。
- 想用快捷键跳转到/about?必须监听
keydown,手动判断组合键后调history.pushState()或设置location.hash - 想让 accesskey 成为辅助入口?只能绑定到已有路由链接(如
<a href="#/about" data-nav>),再靠 JS 拦截 click 并 preventDefault,否则它会走默认跳转或刷新 - accesskey 值必须是单字符(
a、0),写accesskey="about"或accesskey="ctrl+a"会被浏览器静默忽略
前端路由接管后,accesskey 更容易被拦截
当你的应用已用 history.pushState 或 location.hash 管理路由时,用户按下 accesskey 组合键,极大概率被以下环节吃掉:
- Chrome/macOS 下
Alt+Option+S和系统截图快捷键冲突,accesskey="s"根本收不到事件 - Firefox 启用
accessibility.typeaheadfind时,Alt+Shift+F直接触发页面内搜索,而非聚焦搜索框 - 焦点落在
<input>或contenteditable区域时,accesskey 逻辑全程不触发——而路由切换常伴随表单输入场景 - Safari 默认关闭 accesskey,需用户手动开启「偏好设置 → 辅助功能 → 使用键盘快捷键访问网页项目」,且开启后激活键仍是
Ctrl+Option+S,和 Chrome/Windows 不一致
真要支持键盘跳转,得绕开 accesskey 自己做
在路由已接管的页面里,可靠做法是监听全局 keydown,结合当前路由状态做响应:
立即学习“前端免费学习笔记(深入)”;
- 用
e.ctrlKey && e.key === 'k'判断 Ctrl+K(Mac 用e.metaKey),别依赖e.code,避免 AZERTY 键盘错判 - 先排除输入场景:
if (['INPUT', 'TEXTAREA', 'SELECT'].includes(e.target.tagName) || e.target.isContentEditable) return - 匹配成功后,调
history.pushState(null, '', '/search')或location.hash = '#/search',再手动 focus 到目标区域(如搜索框) - 务必调
e.preventDefault(),否则 Ctrl+R 会刷新、Ctrl+T 会开新标签——拦错了比不拦更糟
唯一可接受的“结合”:语义化锚点 + 路由 fallback
如果你坚持要保留 accesskey,唯一较稳妥的用法是配合原生锚点跳转(非路由跳转),并确保服务端或 history fallback 配置正确:
- 写
<a href="#main-content" accesskey="0" title="跳至主内容(Alt+0)">跳至主内容</a> - 目标元素加
id="main-content",且确保它可聚焦(tabindex="-1"或tabindex="0") - 若用 history 模式,Nginx 必须配置
try_files $uri $uri/ /index.html;,否则用户按完 accesskey 再刷新,会 404 - 别指望
accesskey="0"在所有环境都生效——Safari 用户看不到提示,iOS 用户根本没反应
真正上线前,最易被忽略的是:accesskey 的存在本身会干扰屏幕阅读器对路由状态变化的播报。它不发事件、不改 ARIA 属性、不通知 assistive tech —— 用户按了键,焦点移了,但不知道“现在在哪”“下一步能干嘛”。这点比技术失效更致命。



















