应使用 <dialog> 元素实现快捷键提示面板,它原生支持模态行为、焦点管理与 showModal() 控制,比手写 div + aria-modal 更轻量且可访问性更好。
用 <dialog> 最合适,它原生支持模态行为、焦点管理与 showModal() 控制,比手写 div + aria-modal 更轻量且可访问性更好。若需兼容 Safari 15.4 以下(不支持 <dialog>),才降级为带 role="dialog" 的 div,并手动处理 Escape 关闭和焦点锁。
<dialog> 默认不渲染在 DOM 主流中,避免影响布局流,也不需要额外 position: fixed
<form method="dialog"> 或显式调用 close(),否则点击遮罩不会自动关闭<dialog> 设 display: none —— 它靠 open 属性控制显隐,设 display 会破坏可访问性状态监听 keydown 时,优先用 event.ctrlKey / event.metaKey 判断修饰键,而不是依赖 event.key 值 —— 比如 Ctrl+/ 在英文键盘是 /,但法语键盘可能是 ?,而 ctrlKey 始终可靠。
document 上监听,而非某个按钮或输入框内,确保全局生效event.preventDefault() 阻止浏览器默认行为(例如 Ctrl+T 开新页),但仅对明确注册的快捷键做,别无差别拦截Ctrl+S(保存)、Ctrl+R(刷新)、Ctrl+Tab(切标签)—— 用户会困惑你的面板为何抢了系统功能别用纯文本拼接,用 <dl><dt><dd> 结构,既利于屏幕阅读器识别「快捷键」与「功能」的对应关系,也方便 CSS 精确控制缩进和分隔。
<dt> 放快捷键,内部用 <kbd> 包裹每个键:比如 <kbd>Ctrl</kbd>+<kbd>K</kbd>,浏览器默认有等宽、浅灰背景样式<dd> 放说明文字,避免用“打开搜索框”这种模糊描述,改用“聚焦到全局搜索输入框”,明确动作目标Ctrl,macOS 用 Cmd),用 JS 动态替换 <kbd>Ctrl</kbd> 为 <kbd>⌘</kbd>,别硬写两套 HTML这是最常踩的坑:没阻止事件冒泡,导致 keydown 触发后,紧接着触发了 keyup 或点击穿透,让 <dialog> 被意外关闭;或者快捷键逻辑里误调了 dialog.close()。
立即学习“前端免费学习笔记(深入)”;
dialog.showModal() 后又立刻执行了 dialog.close()(比如放在了某个 toggle 函数里,逻辑分支没兜住)document 上对 click 做了全局关闭(例如点击任意处关闭弹窗),这类逻辑要加 event.target === dialog 判断<dialog> 的 showModal() 调用有微小延迟,若紧接着操作 DOM(比如往里面 append 内容),可能因未渲染完成导致尺寸计算错误 —— 改用 requestAnimationFrame 延迟插入内容<button>? 或 <button>快捷键</button>,且该按钮的 accesskey 设为 "h" 或 "k",让键盘用户能先摸到入口。