鍵碼檢視器

按下按鍵即可讀取 KeyboardEvent 的全部屬性:key、code、keyCode、which、location 以及 ctrl、shift、alt、meta 標誌,並可複製完整 JSON。

按下一個鍵,看看瀏覽器究竟報告了什麼。 點選下方捕獲區域,然後按下任意按鍵或組合鍵。KeyboardEvent 的每個屬性都會並排顯示,讓你在編寫快捷鍵處理邏輯時能選對屬性,而不是靠猜。

event.key
event.code
event.keyCode
event.which
event.location
按下的修飾鍵

key、code 與 keyCode 並不是一回事

三個屬性,三個不同的問題

KeyboardEvent 提供了多種標識按鍵的方式,它們回答的問題其實各不相同。event.key 是在應用鍵盤佈局和修飾鍵之後,按鍵所產生的字元或具名值。按下物理 A 鍵得到 a,同時按住 Shift 得到 A,而在 Dvorak 或 AZERTY 佈局上則可能是完全不同的字母。具名按鍵會以描述性字串出現,例如 EnterEscapeArrowLeftF5

event.code 標識的則是物理按鍵位置,使用一套與佈局無關、基於假想美式鍵盤的名稱。位於 A 鍵位置的按鍵始終是 KeyA,無論使用者佈局實際輸出什麼。頂部數字行是 Digit1Digit0,數字小鍵盤則報告 Numpad1 之類的名稱,因此你能區分兩排數字。

event.keyCode 及其孿生的 event.which 是遺留的數字識別符號。二者在規範上均已廢棄,卻依然在所有瀏覽器中實現,並且對標點符號的取值在各瀏覽器間並不一致。維護老程式碼時它們仍值得關注,但新的快捷鍵處理應當使用 keycode

在 key 和 code 之間做選擇

經驗法則很簡單:位置重要時用 code,含義重要時用 key。把移動繫結到 WASD 的遊戲應該用 code,因為玩家左手下方的那一簇物理按鍵在 AZERTY 鍵盤上應保持原位,儘管它實際輸出的是 ZQSD。把「儲存」繫結到 Ctrl+S 的文本編輯器則應該用 key,因為使用者想到的是字母 S,而不是 A 旁邊的那個鍵。

修飾鍵是獨立的布林值:ctrlKeyshiftKeyaltKeymetaKey。請顯式檢測它們,而不要從 key 推斷;同時要記住主快捷鍵修飾符在 macOS 上是 Command,在其他平臺上是 Control。常見寫法是接受 event.metaKey || event.ctrlKey,讓同一段處理邏輯覆蓋兩個平臺。

event.location 用於區分重複按鍵。標準按鍵為 0,成對按鍵中的左側(如左 Shift)為 1,右側為 2,數字小鍵盤上的按鍵為 3。

實踐中的坑

並非所有按鍵都會產生你期望的事件。瀏覽器會為自己保留一些組合——Ctrl+W、Ctrl+T 和 Command+Q 通常在頁面看到之前就已關閉標籤頁或退出應用,preventDefault 也無法奪回它們。任何快捷鍵都應在真實瀏覽器視窗中測試,而不要假定它一定能到達你的處理函式。

按住某個鍵會在首次事件之後產生一連串重複事件,其 event.repeat 為 true。若快捷鍵只應觸發一次,就忽略重複事件;若行為是連續性的(例如滾動或移動游標),則應當響應它們。

最後,keydownkeyup 描述的是按鍵,而描述字元的 keypress 已從標準中移除。處理文本輸入時,更推薦監聽 input 事件或讀取 beforeinput,它們對輸入法組字、自動完成和移動端鍵盤的處理都遠比任何按鍵級事件可靠。

開源說明:使用原生 JavaScript 實現,不依賴第三方庫。

常見問題

快捷鍵應該用 key 還是 code?
物理位置重要時用 `code`,例如遊戲中的 WASD 移動;含義重要時用 `key`,例如儲存用的 Ctrl+S,這樣快捷鍵會跟隨使用者自己的鍵盤佈局。
keyCode 既然廢棄了為什麼還能用?
它早於支援佈局感知的事件出現,且對標點符號在各瀏覽器返回的數字並不一致。所有引擎出於相容性仍在實現它,但規範建議新程式碼使用 `key` 和 `code`。
按 Ctrl+W 或 Command+Q 沒有任何反應。
這些組合被瀏覽器或作業系統佔用,在頁面收到之前就已被處理。普通網頁沒有可靠的方式攔截它們。
如何寫一個同時適配 macOS 和 Windows 的快捷鍵?
用 `event.metaKey || event.ctrlKey` 接受任一主修飾鍵。它在 macOS 上對應 Command,在 Windows 和 Linux 上對應 Control,無需按 User-Agent 分支處理。
location 為 3 是什麼意思?
表示該鍵位於數字小鍵盤上。1 和 2 分別表示 Shift、Control 這類成對按鍵的左側和右側,0 表示沒有重複的普通按鍵。
可以用它來實現文本輸入處理嗎?
更好的做法是監聽 `input` 事件。按鍵事件會遺漏輸入法組字、自動完成以及許多移動端虛擬鍵盤的輸入,而這些 `input` 都能正確上報。