KeyboardEvent: key 屬性
KeyboardEvent 介面的只讀屬性 key 返回使用者按下的鍵的值,該值會考慮修飾鍵(如 Shift)的狀態以及鍵盤的區域設定和佈局。
值
字串。
其值確定方式如下:
- 如果按下的鍵具有可列印的表示形式,則返回的值是一個非空的 Unicode 字元字串,其中包含該鍵的可打印表示形式。例如:如果按下的鍵是 Space 鍵,則返回值是單個空格(
" ")。如果按下的鍵是 B 鍵,則返回值是字串"b"。但是,如果同時按下了 Shift 鍵(因此shiftKey為true),則返回值是字串"B"。 - 如果按下的鍵是控制鍵或特殊字元,則返回值是 預定義鍵值 之一。
- 如果
KeyboardEvent表示按下了一個死鍵,則鍵值為"Dead"。 - 一些特殊鍵盤鍵(例如多媒體鍵盤上用於控制媒體的擴充套件鍵)在 Windows 上不會生成鍵碼;相反,它們會觸發
WM_APPCOMMAND事件。這些事件會對映到 DOM 鍵盤事件,並列在 Windows 的“虛擬鍵碼”中,儘管它們實際上並不是鍵碼。 - 如果無法識別該鍵,則返回值是
Unidentified。
KeyboardEvent 序列
每個 KeyboardEvent 都是按預定的序列觸發的。對於給定的按鍵操作,假設沒有呼叫 Event.preventDefault,觸發的 KeyboardEvent 序列如下:
- 首先會觸發一個
keydown事件。如果按鍵被繼續按下並且該鍵產生一個字元鍵,則該事件將以平臺實現依賴的間隔繼續觸發,並且KeyboardEvent.repeat只讀屬性將設定為true。 - 如果該鍵產生一個字元鍵,該字元鍵會插入到可能的
<input>、<textarea>或HTMLElement.contentEditable設定為 true 的元素中,則會按順序觸發beforeinput和input事件型別。請注意,其他一些實現可能會觸發keypress事件(如果支援)。當按鍵被按下時,事件會重複觸發。 - 當按鍵被釋放時,會觸發一個
keyup事件。這完成了整個過程。
在序列 1 和 3 中,KeyboardEvent.key 屬性會被定義並根據前面定義的規則適當地設定為某個值。
KeyboardEvent 序列示例
比較使用美國鍵盤佈局和使用英國鍵盤佈局與 Shift 和 2 鍵互動時生成的事件序列。
嘗試使用以下兩個測試用例進行實驗:
- 按下並按住 Shift 鍵,然後按下 2 鍵並釋放它。接下來,釋放 Shift 鍵。
- 按下並按住 Shift 鍵,然後按下並按住 2 鍵。釋放 Shift 鍵。最後,釋放 2 鍵。
HTML
<div class="fx">
<div>
<textarea rows="5" name="test-target" id="test-target"></textarea>
<button type="button" name="btn-reset" id="btn-reset">Reset</button>
</div>
<div class="flex">
<pre id="console-log"></pre>
</div>
</div>
CSS
.fx {
-webkit-display: flex;
display: flex;
margin-left: -20px;
margin-right: -20px;
}
.fx > div {
padding-left: 20px;
padding-right: 20px;
}
.fx > div:first-child {
width: 30%;
}
.flex {
-webkit-flex: 1;
flex: 1;
}
#test-target {
display: block;
width: 100%;
margin-bottom: 10px;
}
JavaScript
const textarea = document.getElementById("test-target");
const consoleLog = document.getElementById("console-log");
const btnReset = document.getElementById("btn-reset");
function logMessage(message) {
consoleLog.innerText += `${message}\n`;
}
textarea.addEventListener("keydown", (e) => {
if (!e.repeat) {
logMessage(`Key "${e.key}" pressed [event: keydown]`);
} else {
logMessage(`Key "${e.key}" repeating [event: keydown]`);
}
});
textarea.addEventListener("beforeinput", (e) => {
logMessage(`Key "${e.data}" about to be input [event: beforeinput]`);
});
textarea.addEventListener("input", (e) => {
logMessage(`Key "${e.data}" input [event: input]`);
});
textarea.addEventListener("keyup", (e) => {
logMessage(`Key "${e.key}" released [event: keyup]`);
});
btnReset.addEventListener("click", (e) => {
let child = consoleLog.firstChild;
while (child) {
consoleLog.removeChild(child);
child = consoleLog.firstChild;
}
textarea.value = "";
});
結果
注意: 在不支援 InputEvent 介面(用於 beforeinput 和 input 事件)的瀏覽器中,日誌輸出的這些行可能會出現不正確的輸出。
情況 1
當按下 Shift 鍵時,首先會觸發 keydown 事件,並且 key 屬性值被設定為字串 Shift。由於我們一直按住該鍵,因此 keydown 事件不會重複觸發,因為它不產生字元鍵。
當按下 2 鍵 時,會為這次新的按鍵觸發另一個 keydown 事件,並且由於活動的修飾鍵 shift,該事件的 key 屬性值被設定為字串 @(適用於美國鍵盤型別)和 "(適用於英國鍵盤型別)。接下來會觸發 beforeinput 和 input 事件,因為該鍵產生了一個字元。
當釋放 2 鍵 時,會觸發一個 keyup 事件,並且 key 屬性將分別保持 @ 和 " 的字串值,具體取決於鍵盤佈局。
當我們最終釋放 shift 鍵時,會為它觸發另一個 keyup 事件,並且 key 屬性值將保持為 Shift。
情況 2
當按下 Shift 鍵時,首先會觸發 keydown 事件,並且 key 屬性值被設定為字串 Shift。由於我們一直按住該鍵,因此 keydown 事件不會重複觸發,因為它不產生字元鍵。
當按下 2 鍵 時,會為這次新的按鍵觸發另一個 keydown 事件,並且由於活動的修飾鍵 shift,該事件的 key 屬性值被設定為字串 @(適用於美國鍵盤型別)和 "(適用於英國鍵盤型別)。接下來會觸發 beforeinput 和 input 事件,因為該鍵產生了一個字元。當按住該鍵時,keydown 事件會重複觸發,並且 KeyboardEvent.repeat 屬性被設定為 true。 beforeinput 和 input 事件也會重複觸發。
當我們釋放 shift 鍵時,會為它觸發一個 keyup 事件,並且 key 屬性值保持為 Shift。此時,請注意,由於修飾鍵 shift 不再處於活動狀態,因此對於重複按下的 2 鍵 的 keydown 事件,key 屬性值現在是 "2"。這同樣適用於 beforeinput 和 input 事件的 InputEvent.data 屬性。
當我們最終釋放 2 鍵 時,會觸發一個 keyup 事件,但 key 屬性將被設定為字串值 2(適用於兩種鍵盤佈局),因為修飾鍵 shift 不再處於活動狀態。
示例
此示例使用 EventTarget.addEventListener() 來監聽 keydown 事件。當它們發生時,會檢查按鍵的值,看它是否是我們程式碼感興趣的按鍵之一,如果是,則以某種方式處理它(可能是透過控制航天器,或者改變電子表格中的選定單元格)。
window.addEventListener("keydown", (event) => {
if (event.defaultPrevented) {
return; // Do nothing if the event was already processed
}
switch (event.key) {
case "ArrowDown":
// Do something for "down arrow" key press.
break;
case "ArrowUp":
// Do something for "up arrow" key press.
break;
case "ArrowLeft":
// Do something for "left arrow" key press.
break;
case "ArrowRight":
// Do something for "right arrow" key press.
break;
case "Enter":
// Do something for "enter" or "return" key press.
break;
case " ":
// Do something for "space" key press.
break;
case "Escape":
// Do something for "esc" key press.
break;
default:
return; // Quit when this doesn't handle the key event.
}
// Cancel the default action to avoid it being handled twice
event.preventDefault();
});
規範
| 規範 |
|---|
| UI 事件 # dom-keyboardevent-key |
瀏覽器相容性
載入中…