JavaScript鍵盤滑鼠事件處理
監聽鍵盤滑鼠事件
監聽某個按鍵事件
當鍵盤上的某個鍵被按下時,會依次觸發一次下面的事件:
- onkeydown: 鍵盤按下這個動作(按下鍵盤)
- onkeypress: 鍵盤被按住(一直按著鍵盤不動)
- onkeyup: 鍵盤被彈起(鬆開鍵盤)
通過監聽keydown事件既可以知道鍵盤被按下:
document.onkeydown = function(event) { // 鍵盤按下時觸發 console.log('key down'); }; document.onkeypress = function(event) { // 鍵盤按住時觸發 console.log('key press'); }; document.onkeyup = function (event) { // 鍵盤彈起時觸發 console.log('key up'); }; // 控制檯資料的順序為:key down -> key press -> key up
注意到鍵盤按下的event
引數,該引數為KeyboardEvent
事件物件,其中包含按鍵相關的一些屬性。其中:
- type: 事件型別,如'keydown'或者'keyup'
- key: 表示按下的鍵盤內容是什麼即鍵值,按下字母'p'時,值為'p'
- code: 表示鍵盤程式碼,按下字母'p'時,值為'KeyP'
- keyCode(過時): 整數,表示鍵碼,每個鍵都有唯一的鍵碼,字母'p'的鍵碼為80
- altKey: 布林值,表示此時的alt鍵是否也按下
- ctrKey: 布林值,表示此時的alt鍵是否也按下
- shiftKey: 布林值,表示此時的shift鍵是否也按下
- metaKey: 布林值,windows平臺表示Window鍵是否同時按下,mac表示Command鍵是否同時按下
- repeat: 布林值,如果一個鍵一直被按著,則其值為true,表示重複
可以通過檢查這些屬性來判斷使用者按下的是什麼鍵,以及是否ctrl和alt等鍵是否同時按下。
document.onkeydown = function(event) { // 鍵盤按下是觸發 console.log('key down: ' + event.key); if (event.altKey) { console.log('alt is active'); } if (event.shiftKey) { console.log('shift is active'); } };
監聽滑鼠事件
相應的也可以監聽滑鼠相關的事件,觸發時的引數event
為MouseEvent
物件型別:
- onclick: 滑鼠點選事件
- ondblclick: 滑鼠雙擊事件
- onmousedown: 滑鼠上的按鈕被按下了
- onmouseup: 滑鼠按下後鬆開時觸發的事件
- onmousemove: 滑鼠移動時觸發的事件
- onmouseout: 滑鼠離開監聽該事件的元素或子元素時觸發的事件
- onmouseover: 滑鼠移動到監聽該事件的元素或子元素時觸發的事件
- onmousewheel: 滑鼠滾輪事件,一般使用onscroll事件
MouseEvent
物件中包含下面比較有用的屬性:
- type: 事件型別,如'mosemove'或者'mousedown'
- button: 整型,觸發滑鼠事件時按下的按鈕編號
- buttons: 整型,觸發滑鼠事件時彈起來的按鈕編號
- clientX: 滑鼠指標在DOM內容區的X座標
- clientY:滑鼠指標在DOM內容區的Y座標
- offsetX: 滑鼠指標相對父節點填充邊緣的X座標
- offsetY: 滑鼠指標相對父節點填充邊緣的Y座標
- screenX: 滑鼠指標在全域性螢幕的X座標
- screenY: 滑鼠指標在全域性螢幕的Y座標
- pageX: 滑鼠指標在整個DOM內容(包括分頁)的X座標
- pageY: 滑鼠指標在整個DOM內容(包括分頁)的Y座標
- altKey: 布林值,表示此時的alt鍵是否也按下
- ctrKey: 布林值,表示此時的alt鍵是否也按下
- shiftKey: 布林值,表示此時的shift鍵是否也按下
- metaKey: 布林值,windows平臺表示Window鍵是否同時按下,mac表示Command鍵是否同時按下
通過滑鼠事件的event
屬性,可以獲取滑鼠點選的位置,這裡有對各種座標的相關介紹
,滑鼠點選時是否按住ctrl等。
監聽連續的按鍵事件實現祕笈開啟
在很多遊戲中,都有隱藏的祕笈,比如上上下下左左右右BABA這樣的祕笈,那麼怎麼在網頁監聽事件,能夠知道使用者是按下了這個祕笈呢?(才不是要在隱藏什麼奇怪的東西才用這個的>_<) 演示地址(輸入祕笈真的有驚喜!):http://asset.uusama.com/example/keycode.html
實現的方法就是用一個數組來記錄連續按鍵的狀態,每次按鍵正確則匹配下一個,直到所有匹配成功,看下面程式碼:
// 上上下下左左右右BABA的鍵值 const secretKey = ['up', 'up', 'down', 'down', 'left', 'left', 'right', 'right', 'b', 'a', 'b', 'a']; // 祕笈的鍵碼 const secretKeyCode = [38, 38, 40, 40, 37, 37, 39, 39, 66, 65, 66, 65]; // 當前按鍵匹配的狀態 let secretKeyCodeStatus = new Array(secretKeyCode.length).fill(0); // 當前正確祕笈按鍵的索引 // let correctCodeIndex = 0; const CORRECT_STATUS = 1;// 表示正確匹配按鍵的狀態 document.onkeydown = function(event) { // 查詢第一個0的位置,即當前按鍵應該匹配的位置 let correctCodeIndex = secretKeyCodeStatus.lastIndexOf(CORRECT_STATUS); correctCodeIndex = correctCodeIndex === -1 ? 0 : correctCodeIndex + 1; // 如果所有的按鍵都正確,則返回 if (correctCodeIndex > secretKeyCode.length) { alert('你成功打開了祕笈!通往哲♂學♂之路啊,我命令你開啟吧!'); return true; } // 如果本次按鍵正確,則記錄 if (event.keyCode === secretKeyCode[correctCodeIndex]) { console.log('keyCode: ' + event.keyCode + ' code: ' + event.code + '--correct,index:' + correctCodeIndex); // 所有按鍵都正確則成功 if (correctCodeIndex + 1 === secretKeyCodeStatus.length) { alert('你成功打開了祕笈!通往哲♂學♂之路啊,我命令你開啟吧!'); // 重置狀態 secretKeyCodeStatus = new Array(secretKeyCode.length).fill(0); return true; } else { // 否則記錄當前按鍵成功 secretKeyCodeStatus[correctCodeIndex] = CORRECT_STATUS; } } else { console.log('keyCode: ' + event.keyCode + ' code: ' + event.code + '--reset'); // 按鍵錯誤則重置 secretKeyCodeStatus = new Array(secretKeyCode.length).fill(0); } };
模擬鍵盤和滑鼠事件
上面我們說明了如何監聽頁面的按鍵和鍵盤事件,但是有的時候我們需要使用程式碼模擬按鈕操作。
比如看到很多圖片的時候,我們需要批量下載,這個時候可以開啟控制檯,寫一段JS程式碼批量模擬下載步驟即可,而不用一個一個的手動點選,非常方便。
模擬滑鼠點選
最簡單的就是模擬點選了,我們只需要選中一個元素,然後執行click函式即可。
下面的程式碼實現在一個表格中,點選每一個圖片。
const images = document.getElementById('content').getElementsByTagName('img'); for (let image of images) { images.click(); }
如果要模擬滑鼠雙擊,或者滑鼠移動,則沒有簡單的函式可以呼叫。這個時候我們需要新建一個MouseEvent
物件,並手動觸發即可。
建立MouseEvent
物件的語法為:const event = new MouseEvent(typeArg, mouseEventInit);
-
typeArg
為滑鼠事件型別,即上面的監聽滑鼠事件去掉on
後的字串,- click: 滑鼠點選事件
- dblclick: 滑鼠雙擊事件
- mousedown: 滑鼠上的按鈕被按下了
- mouseup: 滑鼠按下後鬆開時觸發的事件
- mousemove: 滑鼠移動時觸發的事件
- mouseout: 滑鼠離開監聽該事件的元素或子元素時觸發的事件
- mouseover: 滑鼠移動到監聽該事件的元素或子元素時觸發的事件
-
mouseEventInit
為MouseEvent
初始化的選項,指定滑鼠事件的各種屬性,可選值如下:- button: 整型,觸發滑鼠事件時按下的按鈕編號
- buttons: 整型,觸發滑鼠事件時彈起來的按鈕編號
- clientX: 滑鼠指標在DOM內容區的X座標
- clientY:滑鼠指標在DOM內容區的Y座標
- offsetX: 滑鼠指標相對父節點填充邊緣的X座標
- offsetY: 滑鼠指標相對父節點填充邊緣的Y座標
- screenX: 滑鼠指標在全域性螢幕的X座標
- screenY: 滑鼠指標在全域性螢幕的Y座標
- pageX: 滑鼠指標在整個DOM內容(包括分頁)的X座標
- pageY: 滑鼠指標在整個DOM內容(包括分頁)的Y座標
- altKey: 布林值,表示此時的alt鍵是否也按下
- ctrKey: 布林值,表示此時的alt鍵是否也按下
- shiftKey: 布林值,表示此時的shift鍵是否也按下
- metaKey: 布林值,windows平臺表示Window鍵是否同時按下,mac表示Command鍵是否同時按下
比如下面的示例在座標200,200處觸發一個滑鼠雙擊事件:
// 建立一個event物件 const createEvent = new MouseEvent('dblclick', { clientX: 300, clientY: 300, }); // 觸發該事件 document.dispatchEvent(createEvent);
可以使用任意的Document
物件的dispatchEvent
方法觸發一個事件,這些觸發的事件和實際發生的事件一模一樣。
模擬鍵盤輸入事件
和模擬滑鼠事件一樣,不過這兒我們要建立一個KeyboardEvent
事件物件。
建立KeyboardEvent
物件的語法類似為:const event = new KeyboardEvent(typeArg, KeyboardEventInit);
-
typeArg
為鍵盤輸入事件型別,即上面的監聽鍵盤輸入事件去掉on
後的字串,- keydown: 鍵盤按下這個動作
- keypress: 鍵盤被按住
- keyup: 鍵盤被彈起
-
KeyboardEventInit
為KeyboardEvent
初始化的選項,指定鍵盤輸入事件的各種屬性,可選值如下:- type: 事件型別,如'keydown'或者'keyup'
- key: 表示按下的鍵盤內容是什麼即鍵值,按下字母'p'時,值為'p'
- code: 表示鍵盤程式碼,按下字母'p'時,值為'KeyP'
- keyCode(過時): 整數,表示鍵碼,每個鍵都有唯一的鍵碼,字母'p'的鍵碼為80
- altKey: 布林值,表示此時的alt鍵是否也按下
- ctrKey: 布林值,表示此時的alt鍵是否也按下
- shiftKey: 布林值,表示此時的shift鍵是否也按下
- metaKey: 布林值,windows平臺表示Window鍵是否同時按下,mac表示Command鍵是否同時按下
- repeat: 布林值,如果一個鍵一直被按著,則其值為true,表示重複
比如實現在按下字母'a'鍵時,自動按下'alt+ctrl+a'可以像下面實現。
// 監聽按鍵事件 document.onkeydown = function(event) { console.log('keyCode: ' + event.keyCode + ' code: ' + event.code + ' alt:' + event.altKey); if (event.keyCode === 65 || event.code === 'KeyA') { // 如果按下的是a鍵,則新建一個a鍵按下的事件並觸發 const createEvent = new KeyboardEvent('keydown', { altKey: true, shiftKey: true, keyCode: 65, code: 'KeyA' }); document.dispatchEvent(createEvent); } };
然後你就會發現上面的函式瘋狂的輸出A鍵被按下,哈哈哈!知道記憶體達到限制!
附錄
最後附上鍵值和鍵碼的對應關係物件,可以直接拷貝使用:
const keyCodes = { 0: 'That key has no keycode', 3: 'break', 8: 'backspace / delete', 9: 'tab', 12: 'clear', 13: 'enter', 16: 'shift', 17: 'ctrl', 18: 'alt', 19: 'pause/break', 20: 'caps lock', 21: 'hangul', 25: 'hanja', 27: 'escape', 28: 'conversion', 29: 'non-conversion', 32: 'spacebar', 33: 'page up', 34: 'page down', 35: 'end', 36: 'home', 37: 'left arrow', 38: 'up arrow', 39: 'right arrow', 40: 'down arrow', 41: 'select', 42: 'print', 43: 'execute', 44: 'Print Screen', 45: 'insert', 46: 'delete', 47: 'help', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5', 54: '6', 55: '7', 56: '8', 57: '9', 58: ':', 59: 'semicolon (firefox), equals', 60: '<', 61: 'equals (firefox)', 63: 'ß', 64: '@ (firefox)', 65: 'a', 66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h', 73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o', 80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v', 87: 'w', 88: 'x', 89: 'y', 90: 'z', 91: 'Windows Key / Left ⌘ / Chromebook Search key', 92: 'right window key', 93: 'Windows Menu / Right ⌘', 95: 'sleep', 96: 'numpad 0', 97: 'numpad 1', 98: 'numpad 2', 99: 'numpad 3', 100: 'numpad 4', 101: 'numpad 5', 102: 'numpad 6', 103: 'numpad 7', 104: 'numpad 8', 105: 'numpad 9', 106: 'multiply', 107: 'add', 108: 'numpad period (firefox)', 109: 'subtract', 110: 'decimal point', 111: 'divide', 112: 'f1', 113: 'f2', 114: 'f3', 115: 'f4', 116: 'f5', 117: 'f6', 118: 'f7', 119: 'f8', 120: 'f9', 121: 'f10', 122: 'f11', 123: 'f12', 124: 'f13', 125: 'f14', 126: 'f15', 127: 'f16', 128: 'f17', 129: 'f18', 130: 'f19', 131: 'f20', 132: 'f21', 133: 'f22', 134: 'f23', 135: 'f24', 144: 'num lock', 145: 'scroll lock', 160: '^', 161: '!', 162: '؛ (arabic semicolon)', 163: '#', 164: '$', 165: 'ù', 166: 'page backward', 167: 'page forward', 168: 'refresh', 169: 'closing paren (AZERTY)', 170: '*', 171: '~ + * key', 172: 'home key', 173: 'minus (firefox), mute/unmute', 174: 'decrease volume level', 175: 'increase volume level', 176: 'next', 177: 'previous', 178: 'stop', 179: 'play/pause', 180: 'e-mail', 181: 'mute/unmute (firefox)', 182: 'decrease volume level (firefox)', 183: 'increase volume level (firefox)', 186: 'semi-colon / ñ', 187: 'equal sign', 188: 'comma', 189: 'dash', 190: 'period', 191: 'forward slash / ç', 192: 'grave accent / ñ / æ / ö', 193: '?, / or °', 194: 'numpad period (chrome)', 219: 'open bracket', 220: 'back slash', 221: 'close bracket / å', 222: 'single quote / ø / ä', 223: '`', 224: 'left or right ⌘ key (firefox)', 225: 'altgr', 226: '< /git >, left back slash', 230: 'GNOME Compose Key', 231: 'ç', 233: 'XF86Forward', 234: 'XF86Back', 235: 'non-conversion', 240: 'alphanumeric', 242: 'hiragana/katakana', 243: 'half-width/full-width', 244: 'kanji', 251: "unlock trackpad (Chrome/Edge)", 255: 'toggle touchpad', }; // 壓縮之後的 const keyCodesMin={0:"That key has no keycode",3:"break",8:"backspace / delete",9:"tab",12:"clear",13:"enter",16:"shift",17:"ctrl",18:"alt",19:"pause/break",20:"caps lock",21:"hangul",25:"hanja",27:"escape",28:"conversion",29:"non-conversion",32:"spacebar",33:"page up",34:"page down",35:"end",36:"home",37:"left arrow",38:"up arrow",39:"right arrow",40:"down arrow",41:"select",42:"print",43:"execute",44:"Print Screen",45:"insert",46:"delete",47:"help",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",58:":",59:"semicolon (firefox), equals",60:"<",61:"equals (firefox)",63:"ß",64:"@ (firefox)",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",91:"Windows Key / Left ⌘ / Chromebook Search key",92:"right window key",93:"Windows Menu / Right ⌘",95:"sleep",96:"numpad 0",97:"numpad 1",98:"numpad 2",99:"numpad 3",100:"numpad 4",101:"numpad 5",102:"numpad 6",103:"numpad 7",104:"numpad 8",105:"numpad 9",106:"multiply",107:"add",108:"numpad period (firefox)",109:"subtract",110:"decimal point",111:"divide",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",124:"f13",125:"f14",126:"f15",127:"f16",128:"f17",129:"f18",130:"f19",131:"f20",132:"f21",133:"f22",134:"f23",135:"f24",144:"num lock",145:"scroll lock",160:"^",161:"!",162:"؛ (arabic semicolon)",163:"#",164:"$",165:"ù",166:"page backward",167:"page forward",168:"refresh",169:"closing paren (AZERTY)",170:"*",171:"~ + * key",172:"home key",173:"minus (firefox), mute/unmute",174:"decrease volume level",175:"increase volume level",176:"next",177:"previous",178:"stop",179:"play/pause",180:"e-mail",181:"mute/unmute (firefox)",182:"decrease volume level (firefox)",183:"increase volume level (firefox)",186:"semi-colon / ñ",187:"equal sign",188:"comma",189:"dash",190:"period",191:"forward slash / ç",192:"grave accent / ñ / æ / ö",193:"?, / or °",194:"numpad period (chrome)",219:"open bracket",220:"back slash",221:"close bracket / å",222:"single quote / ø / ä",223:"`",224:"left or right ⌘ key (firefox)",225:"altgr",226:"< /git >, left back slash",230:"GNOME Compose Key",231:"ç",233:"XF86Forward",234:"XF86Back",235:"non-conversion",240:"alphanumeric",242:"hiragana/katakana",243:"half-width/full-width",244:"kanji",251:"unlock trackpad (Chrome/Edge)",255:"toggle touchpad",};