监听键盘事件应使用 keydown,因其能可靠捕获所有按键(含功能键),而 keypress 已废弃、keyup 适合松开后响应;需在 document 上监听,用 e.key/e.code 判断按键,e.preventDefault() 阻止默认行为,并兼容 metaKey/ctrlKey、排除可编辑元素、避免冲突组合键。

监听键盘事件要用 keydown,不是 keypress 或 keyup
现代浏览器中,keydown 是唯一能可靠捕获所有按键(包括 Ctrl、ArrowUp、Escape)的事件;keypress 已被废弃,且不触发功能键;keyup 适合松开后响应,但快捷键逻辑通常需要“按下即生效”。
直接在 document 上监听,避免聚焦限制:
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 's') {
e.preventDefault(); // 阻止浏览器默认保存行为
console.log('自定义保存触发');
}
});-
e.preventDefault()必须加在组合键逻辑里,否则Ctrl+S仍会弹出保存对话框 - 不要用
e.keyCode或e.which—— 已废弃,一律用e.key(返回字符串如"a"、"Enter")或e.code(返回物理键位如"KeyA"、"Enter") - 若页面有输入框(
input、textarea),需判断e.target是否为可编辑元素,避免干扰用户打字:
if (e.target.matches('input, textarea, [contenteditable]')) return;区分修饰键组合:别只靠 e.ctrlKey 判断
用户可能用 Cmd+S(macOS)、Ctrl+S(Windows/Linux),甚至 Alt+Shift+K 自定义组合。硬编码 e.ctrlKey 会漏掉 macOS 用户。
- 用
e.metaKey捕获 macOS 的 Command 键,与e.ctrlKey逻辑“或”处理:
const isMod = e.ctrlKey || e.metaKey;
if (isMod && e.key === 's') { /* 保存 */ }- 避免同时依赖多个修饰键却没校验顺序 —— 浏览器不保证
e.shiftKey和e.key在同一帧完全同步,但实际中只要不极端高频连按,e.shiftKey && e.key === 'F'是安全的 - 慎用
e.repeat:长按按键会连续触发,若快捷键是“音量+”,你可能只想响应首次按下,加if (e.repeat) return;
快捷键冲突:浏览器、扩展、系统级行为必须绕开
某些组合键被操作系统或浏览器强占,JS 无法拦截(如 Cmd+Q 关闭 macOS 应用、F5 刷新、Esc 退出全屏)。强行绑定无效,还会让代码显得不可靠。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
立即学习“前端免费学习笔记(深入)”;
- 可安全使用的常见组合:
-
Ctrl/Cmd + S(需e.preventDefault()) -
Ctrl/Cmd + F(搜索,但注意别和浏览器 Ctrl+F 冲突 —— 可先e.preventDefault(),再聚焦到你的搜索框) -
Alt + ArrowLeft/Right(导航类操作,浏览器不默认占用) - 绝对避免:
Ctrl+T、Ctrl+W、F12、Ctrl+R—— 这些无法被 JS 阻止,监听了也白监听
测试时务必在无扩展的隐身窗口验证,很多快捷键被广告拦截插件或密码管理器劫持。
React/Vue 项目里快捷键失效?问题常出在事件挂载时机
单页应用中,document.addEventListener 如果写在组件 useEffect 或 mounted 里,但组件卸载后没清理,会导致多次绑定、内存泄漏;更常见的是:组件还没挂载完,用户就按了键,事件根本没注册上。
- 在根组件(如
App.js)的顶层useEffect中注册,并返回清除函数:
useEffect(() => {
const handler = (e) => { /* ... */ };
document.addEventListener('keydown', handler);
return () => document.removeEventListener('keydown', handler);
}, []);- Vue 3 的
onMounted/onUnmounted同理,别写在methods里手动调用 - 如果快捷键要随路由变化(比如仅在编辑页生效),别用
v-if控制监听器开关 —— 改用条件判断逻辑内部,保持监听器常驻更稳定
最易忽略的一点:快捷键逻辑里访问的 state 或 props 必须用最新值,否则闭包会卡在初始状态 —— React 用 useRef 缓存最新值,Vue 用 getCurrentInstance() 或 computed 响应式取值。


















