如何高效的开发监听前端组合键、快捷键
最近项目中有个需求,使用快捷键,然后就自行开发了一个库用来监听组合键,具体参考下面的demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body></body>
<script>
function combinationKey(keys) {
let combinationKeyList = []
let keyQueue = []
const mouseMap = Object.values(combinationKey.MOUSE)
if (!keys) {
console.warn('needs keys array')
return
}
combinationKeyList = keys
const dispatchForCode = (event) => {
return new Promise((resolve) => {
let code = undefined
if (event.key !== undefined) {
code = event.key
} else if (event.keyCode !== undefined) {
// 未对 keyCode 做兼容
code = event.keyCode
}
resolve(code)
})
}
function keyDownTrigger(e) {
e.preventDefault()
dispatchForCode(e).then((code) => {
if (typeof code === 'number') {
keyQueue.push(code)
} else {
keyQueue.push(code.toLowerCase())
}
})
}
function convertArrayToString(arr) {
return JSON.stringify(arr)
}
function indexOfCombinationKeyList(combinationKeyList, keyQueue) {
const _keyQueue = convertArrayToString(keyQueue)
return combinationKeyList.findIndex((item) => convertArrayToString(item.keys) === _keyQueue)
}
function deleteKeyFromKeyQueue (code) {
let deleteIndex = keyQueue.indexOf(code)
keyQueue.splice(deleteIndex, 1)
}
function keyUpTrigger(e) {
const index = indexOfCombinationKeyList(combinationKeyList, keyQueue)
if (index > -1) {
combinationKeyList[index].execute()
} else {
keyQueue = []
}
dispatchForCode(e).then((code) => {
deleteKeyFromKeyQueue(code)
})
}
function mouseDownTrigger (e) {
keyQueue.push(mouseMap[e.button])
}
function mouseUpTrigger (e) {
keyUpTrigger(e)
}
// 可调用 destroy 方法用来销毁监听事件
function destroy() {
window.removeEventListener('keydown', keyDownTrigger)
window.removeEventListener('keyup', keyUpTrigger)
window.removeEventListener('mousedown', mouseDownTrigger)
window.removeEventListener('mouseup', mouseUpTrigger)
}
window.addEventListener('keydown', keyDownTrigger, false)
window.addEventListener('keyup', keyUpTrigger, false)
window.addEventListener('mousedown', mouseDownTrigger, false)
window.addEventListener('mouseup', mouseUpTrigger, false)
return {
destroy
}
}
combinationKey.MOUSE = {
LEFT_MOUSE: 'leftMouse',
WHEEL_MOUSE: 'wheelMouse',
RIGHT_MOUSE: 'rightMouse',
}
combinationKey.KEY = {
TAB: 'tab',
ENTER: 'enter',
CTRL: 'control',
SHIFT: 'shift',
ALT: 'alt',
ESC: 'escape',
CAPS_LOCK: 'CapsLock',
META: 'Meta',
SPACE: ' ',
ARROW_UP: 'ArrowUp',
ARROW_DOWN: 'ArrowDown',
ARROW_LEFT: 'ArrowLeft',
ARROW_RIGHT: 'ArrowRight',
BACKSPACE: 'Backspace',
F1: 'F1',
F2: 'F2',
F3: 'F3',
F4: 'F4',
F5: 'F5',
F6: 'F6',
F7: 'F7',
F8: 'F8',
F9: 'F9',
F10: 'F10',
F11: 'F11',
F12: 'F12',
}
combinationKey([
{
// 要按下的键,数组的顺序是按下的顺序
keys: [combinationKey.KEY.SPACE],
// 按键触发后要执行的函数
execute: () => {
console.log('SPACE')
},
},
{
keys: ['control', 's'],
execute: () => {
console.log('ctrl + s')
},
},
{
keys: ['control', 'shift', 's'],
execute: () => {
console.log('ctrl + shift + s')
},
},
{
keys: ['shift', combinationKey.MOUSE.LEFT_MOUSE],
execute: () => {
console.log('shift + leftMouse')
},
},
{
keys: ['shift', combinationKey.MOUSE.WHEEL_MOUSE],
execute: () => {
console.log('shift + wheelMouse')
},
},
])
</script>
</html>