今天分享如何快速实现js快捷键监听
所需环境:
- 浏览器
- js
实现目标
- mac/win兼容,一套代码,多个平台
- 支持快捷键监听/单按键监听
- 事件是否冒泡可设置
- 使用方式简单
- 快速挂载与卸载
- 4行代码实现组合键监听
代码原理
把键盘监听事件挂载在document上,当键盘事件发生时,依次匹配事先订阅的快捷键/单按键事件,
如果有匹配到对应的订阅,则进行事件回调,并且停止键盘事件的回调。按下的按键进行转换,把mac
/win
的键盘差异进行了兼容
实战项目:MyPrint
操作简单,组件丰富的一站式打印解决方案打印设计器
体验地址:前往
代码仓库:github
代码仓库:gitee
实现效果
js快捷键实战
核心代码
interface keyListener {
keys: Array<string | ((event: KeyboardEvent) => boolean)>;
// ALL 全部符合才算| ANY 匹配到任意一个就算
matchType: 'ALL' | 'ANY';
callback: (keyStr: string) => void;
// 是否停止时间传播
stop: boolean;
}
// 多平台键盘转换
const keyConvert = {
Ctrl: ['Meta', 'Ctrl']
} as Record<string, Array<string>>;
const eventListeners: Array<keyListener> = [];
const downKeyList = {
} as any;
export function addKeyboardEvent() {
document.addEventListener('keydown', keyDown);
document.addEventListener('keyup', keyUp);
const handlers = {
subscribe(keys: Array<string | ((event: KeyboardEvent) => boolean)>, callback: (keyStr: string) => void, stop = true) {
eventListeners.push({
keys,
matchType: 'ALL',
callback,
stop
});
return handlers;
},
subscribeAny(keys: Array<string | ((event: KeyboardEvent) => boolean)>, callback: (keyStr: string) => void, stop = true) {
eventListeners.push({
keys,
matchType: 'ANY',
callback,
stop
});
return handlers;
}
};
return handlers;
}
export function removeKeyboardEvent() {
document.removeEventListener('keydown', keyDown);
document.removeEventListener('keyup', keyUp);
}
function keyUp(event: KeyboardEvent) {
delete downKeyList[convertKey(event.key)];
}
function convertKey(key: string) {
for (let keyConvertKey in keyConvert) {
let convertList = keyConvert[keyConvertKey];
if (convertList.includes(key)) {
return keyConvertKey;
}
}
return key;
}
function keyDown(event: KeyboardEvent) {
// 如果需要输入框,则不监听组合键
if ((event.target as HTMLElement).tagName === 'INPUT' || (event.target as HTMLElement).tagName === 'TEXTAREA') {
// console.log('This event is triggered by an input or textarea!');
return;
}
for (let eventListener of eventListeners) {
let matchResult = false
if (eventListener.matchType == 'ALL') {
matchResult = matchAll(event, eventListener)
} else {
matchResult = matchAny(event, eventListener)
}
if (matchResult) {
break
}
}
}
function matchAll(event: KeyboardEvent, keyListener: keyListener) {
const {
keys, callback, stop} = keyListener;
let isTrigger = true;
let keyStr = ''<