在任何页面上自定义键盘快捷键 —— 4 种 JavaScript 模式
你每天花好几个小时泡在某个后台面板里,它没有 Ctrl+S 保存、没有 Ctrl+Enter 提交、没有 / 聚焦搜索框。四种 JS 模式,让你加上自己的快捷键 —— 不管网站作者当初是怎么想的。
模式 1 —— 全局 keydown 监听器
基础。在 document 上捕获 keydown,检查修饰键,执行动作:
document.addEventListener('keydown', (e) => {
// Ctrl+Shift+S → 点击 "保存" 按钮
if (e.ctrlKey && e.shiftKey && e.key === 'S') {
e.preventDefault();
document.querySelector('button[type="submit"]')?.click();
}
// Ctrl+/ → 聚焦搜索框
if (e.ctrlKey && e.key === '/') {
e.preventDefault();
document.querySelector('input[type="search"], input[name="q"]')?.focus();
}
});
关键:用 e.preventDefault(),让浏览器不要执行它默认的快捷键(Ctrl+S = 保存页面)。否则用户得到的是 HTML 保存对话框,而不是你的动作。
模式 2 —— 上下文敏感(仅在字段之外)
单个按键(例如 j/k = 在元素间导航)不能在用户正在 textarea 里打字时触发。根据 document.activeElement 过滤:
function isTyping() {
const el = document.activeElement;
if (!el) return false;
const tag = el.tagName.toLowerCase();
return tag === 'input' || tag === 'textarea'
|| el.isContentEditable;
}
document.addEventListener('keydown', (e) => {
if (isTyping()) return;
// j/k = 在列表卡片间导航(Gmail 风格)
if (e.key === 'j') {
e.preventDefault();
document.querySelector('.card.focused')
?.nextElementSibling?.classList.add('focused');
}
});
没有这个过滤,在登录框里打的一个 j 就会触发你的导航 —— 用户永远没法输入邮箱 john@example.com。
模式 3 —— 按键序列(Vim 风格)
有些动作值得用两个连续按键,例如 gg = 滚动到顶部(像 Gmail/GitHub 那样):
let lastKey = null;
let lastKeyTime = 0;
const SEQ_TIMEOUT_MS = 500;
document.addEventListener('keydown', (e) => {
if (isTyping()) return;
const now = Date.now();
// gg → 滚动到顶部
if (e.key === 'g' && lastKey === 'g' && (now - lastKeyTime) < SEQ_TIMEOUT_MS) {
window.scrollTo({ top: 0, behavior: 'smooth' });
lastKey = null;
return;
}
// G (shift+g) → 滚动到底部
if (e.key === 'G' && e.shiftKey) {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
return;
}
lastKey = e.key;
lastKeyTime = now;
});
模式 4 —— 帮助浮层(?)
如果你记不住快捷键,它们就毫无用处。? 键弹出一个带着你清单的浮层:
const SHORTCUTS = [
['Ctrl+S', '保存表单'],
['Ctrl+/', '聚焦搜索框'],
['j / k', '下一张 / 上一张卡片'],
['gg', '滚动到顶部'],
['G', '滚动到底部'],
];
function showHelp() {
const overlay = document.createElement('div');
overlay.style.cssText = `
position: fixed; inset: 0; background: rgba(0,0,0,.6);
display: flex; align-items: center; justify-content: center;
z-index: 999999;
`;
overlay.innerHTML = `
快捷键
${SHORTCUTS.map(([k, v]) => `
${k}
${v}
`).join('')}
Esc 或点击 = 关闭
`;
overlay.onclick = () => overlay.remove();
document.body.appendChild(overlay);
}
document.addEventListener('keydown', (e) => {
if (isTyping()) return;
if (e.key === '?') { e.preventDefault(); showHelp(); }
if (e.key === 'Escape') document.querySelector('div[style*="rgba(0,0,0,.6)"]')?.remove();
});
坑
- 与浏览器的冲突:Ctrl+T、Ctrl+W、Ctrl+L 无法被拦截。Chrome 在 OS 层面保留了它们。用别的(Ctrl+Shift+某键、Alt+某键)。
- 与操作系统的冲突:macOS 上的 Cmd+Tab、Windows 上的 Alt+Tab —— 同理。别硬碰硬。
- 带路由的 SPA —— 有些 SPA 会动态注入它们自己的 keydown 监听器。你的监听器可能在它之前触发(用 stopPropagation),也可能在它之后(你可以通过 removeEventListener 恢复原始的)。
- 键盘布局差异 ——
e.key返回本地化的字母,e.code返回物理按键位置。对 j/k 风格的快捷键用e.key;对位置相关的(例如 WASD)用e.code。
如何在 JustZix 中接入
- 安装 JustZix。
- 按面板设规则:URL 模式
https://admin.mycompany.com/*,JavaScript = 本文的模式 1+2+4。 - 同步:笔记本和工作机上是同一套快捷键。
- 分享:给同事发一个分享链接 —— 他们一键导入你的快捷键。
免费安装 JustZix,以键盘的速度工作。
为这篇文章评分
暂无评分 — 成为第一个。