全局快捷键监听导致其他输入框无法输入怎么办?
在React项目里实现全局快捷键Ctrl+S触发保存功能时,发现输入框里按Ctrl+S会同时触发保存和输入下划线。试过用event.preventDefault(),但其他页面的搜索框输入斜杠时也会被拦截,怎么精准判断快捷键触发场景?
现在代码是这样写的:
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 's') {
saveData();
e.preventDefault();
}
});
但用户在文本框里正常输入”cs”组合时,光标会停在倒数第二个字符位置,感觉监听层级有问题,有什么更好的实现方式吗?
解决方法很简单,就是在触发 saveData 前判断一下当前焦点是否在输入框里。比如:
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 's') {
const target = e.target;
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
return; // 输入框里就直接返回,不触发保存
}
saveData();
e.preventDefault();
}
});
这样就能避免输入框里按 Ctrl+S 被同时识别成保存和输入下划线的问题。至于你说的输入 "cs" 时光标停在倒数第二个字符的问题,也正是因为快捷键监听干扰了输入行为,这套判断加进去以后应该就能恢复正常了。
如果你后面还想加更多快捷键,或者需要更灵活的控制,插件可以考虑用 mousetrap 或者 keymaster.js,这些库已经帮你处理了大部分场景。不过现在这个需求直接用原生也能搞定,不用额外加依赖。
document.addEventListener('keydown', (e) => {
if ((e.ctrlKey || e.metaKey) && e.key === 's') {
if (['INPUT', 'TEXTAREA'].includes(document.activeElement?.tagName)) return;
saveData();
e.preventDefault();
}
});
这样输入框里按ctrl+s就不会触发保存了,其他快捷键同理加判断就行。