如何高效的開發監聽前端組合鍵、快捷鍵
阿新 • • 發佈:2020-12-22
最近專案中有個需求,使用快捷鍵,然後就自行開發了一個庫用來監聽組合鍵,具體參考下面的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>