JS鍵盤事件(非常詳細)

2020-07-16 10:05:12
在 JavaScript 中,當使用者操作鍵盤時,會觸發鍵盤事件,鍵盤事件主要包括下面 3 種型別:
  • keydown:在鍵盤上按下某個鍵時觸發。如果按住某個鍵,會不斷觸發該事件,但是 Opera 瀏覽器不支援這種連續操作。該事件處理常式返回 false 時,會取消預設的動作(如輸入的鍵盤字元,在 IE 和 Safari 瀏覽器下還會禁止keypress 事件響應)。
  • keypress:按下某個鍵盤鍵並釋放時觸發。如果按住某個鍵,會不斷觸發該事件。該事件處理常式返回 false 時,會取消預設的動作(如輸入的鍵盤字元)。
  • keyup:釋放某個鍵盤鍵時觸發。該事件僅在鬆開鍵盤時觸發一次,不是一個持續的響應狀態。

當獲取使用者正按下鍵碼時,可以使用 keydown、keypress 和 keyup 事件獲取這些資訊。其中 keydown 和 keypress 事件基本上是同義事件,它們的表現也完全一致,不過一些瀏覽器不允許使用 keypress 事件獲取按鍵資訊。所有元素都支援鍵盤事件,但鍵盤事件多被應用在表單輸入中。

範例

下面範例實時捕獲鍵盤操作的各種細節,即鍵盤響應事件型別及對應的鍵值。
<textarea id="key"></textarea>
<script>
    var key = document.getElementById("key");
    key.onkeydown =f;  //註冊keydown事件處理常式
    key.onkeyup = f;  //註冊keyup事件處理常式
    key.onkeypress = f;  //註冊keypress事件處理常式
    function f (e) {
        var e = e || window.event;  //標準化事件處理
        var s = e.type + " " + e.keyCode;  //獲取鍵盤事件型別和按下的值
        key.value = s;
    }
</script>

鍵盤事件屬性

鍵盤定義了很多屬性,如下表所示。利用這些屬性可以精確控制鍵盤操作。鍵盤事件屬性一般只在鍵盤相關事件發生時才會存在於事件物件中,但是 ctrlKey 和 shiftKey 屬性除外,因為它們可以在水保事件中存在。例如,當按下 Ctrl 或Shift 鍵時單擊滑鼠操作。
鍵盤事件定義的屬性
屬性 說明
keyCode 該屬性包含鍵盤中對應鍵位的鍵值
charCode 該屬性包含鍵盤中對應鍵位的 Unicode 編碼,僅 DOM 支援
target 發生事件的節點(包含元素),僅 DOM 支援
srcElement 發生事件的元素,僅 IE 支援
shiftKey 是否按下 Shift 鍵,如果按下返回 true,否則為false
ctrlKey 是否按下 Ctrl 鍵,如果按下返回 true,否則為false
altKey 是否按下 Alt 鍵,如果按下返回 true,否則為false
metaKey 是否按下 Mtea 鍵,如果按下返回 true,否則為false,僅 DOM 支援

範例1

ctrlKey 和 shiftKey 屬性可存在於鍵盤和滑鼠事件中,表示鍵盤上的 Ctrl 和 Shift 鍵是否被按住。下面範例能夠監測 Ctrl 和 Shift 鍵是否被同時按下。如果同時按下,且滑鼠單擊某個頁面元素,則會把該元素從頁面中刪除。
document.onclick = function (e) {
    var e = e || window.event;  //標準化事件物件
    var t = e.target || e.srcElement;  //獲取發生事件的元素,相容IE和DOM
    if (e.ctrlKey && e.shiftKey) {  //如果同時按下Ctrl和Shift鍵
        t.parentNode.removeChild(t);  //移出當前元素
    }
}

keyCode 和 charCode 屬性使用比較複雜,但是它們在實際開發中又比較常用,故比較這兩個屬性在不同事件型別和不同瀏覽器中的表現時非常必要的,如下表所示。讀者可以根據需要有針對性的選用事件響應型別和參照屬性值。

keyCode 和 charCode 屬性值
屬性 IE 事件模型 DOM 事件模型
keyCode(keypress) 返回所有字元鍵的正確值,區分大寫狀態(65~90)和小寫狀態(97~122) 功能鍵返回正確值,而 Shift、Ctrl、Alt、PrintScreen、ScrollLock 無返回值,其他所有鍵值都返回 0
keyCode(keydown) 返回所有鍵值(除 PrintScreen 鍵),字母鍵都以大寫狀態顯示鍵值(65~90) 返回所有鍵值(除 PrintScreen 鍵),字母鍵都以大寫狀態顯示鍵值(65~90)
keyCode(keyup) 返回所有鍵值(除 PrintScreen 鍵),字母鍵都以大寫狀態顯示鍵值(65~90) 返回所有鍵值(除 PrintScreen 鍵),字母鍵都以大寫狀態顯示鍵值(65~90)
charCode(keypress) 不支援該屬性 返回字元鍵,區分大寫狀態(65~90)和小寫狀態(97~122),Shift、Ctrl、Alt、PrintScreen、ScrollLock 無返回值,其他所有鍵值都返回 0
charCode(keydown) 不支援該屬性 所有鍵值為 0
charCode(keyup) 不支援該屬性 所有鍵值為 0

某些鍵的可用性不是很正確,如 PageUp 和 Home 鍵等。不過常用功能鍵和字元鍵都是比較穩定的,如下表所示。

鍵位和碼值對照表
鍵位 碼值 鍵位 碼值
0~9(數位鍵) 48~57 A~Z(字母鍵) 65~90
Backspace(退格鍵) 8 Tab(製表鍵) 9
Enter(確認鍵) 13 Space(空格鍵) 32
Left arrow(左箭頭鍵) 37 Top arrow(上箭頭鍵) 38
Right arrow(右箭頭鍵) 39 Down arrow(下箭頭鍵) 40

範例2

下面範例演示了如何使用方向鍵控制頁面元素的移動效果。
<div id="box"></div>
<script>
    var box = document.getElementById("box");  // 獲取頁面元素的參照指標
    box.style.position = "absolute";  // 色塊絕對定位
    box.style.width = "20px";  // 色塊寬度
    box.style.height = "20px";  // 色塊高度
    box.style.backgroundColor = "red";  // 色塊背景
    document.onkeydown = keyDown;
    //在Document物件中註冊keyDown事件處理常式
    function keyDown(event){  // 方向鍵控制元素移動函數
        var event = event || window.event;  // 標準化事件物件
        switch(event.keyCode){  // 獲取當前按下鍵盤鍵的編碼
            case 37 :  // 按下左箭頭鍵,向左移動5個畫素
                box.style.left = box.offsetLeft - 5  + "px";
                break;
            case 39 :  // 按下右箭頭鍵,向右移動5個畫素
                box.style.left = box.offsetLeft + 5 + "px";
                break;
            case 38 :  // 按下上箭頭鍵,向上移動5個畫素
                box.style.top = box.offsetTop  - 5 + "px";
                break;
            case 40 :  // 按下下箭頭鍵,向下移動5個畫素
                box.style.top = box.offsetTop  + 5 + "px";
                break;
        }
        return false
    }
</script>
在上面範例中,首先獲取頁面元素,通過 CSS 指令碼控制元素絕對定位、大小和背景色。然後在 document 物件上註冊滑鼠按下事件型別處理常式,在事件回撥函數 keyDown() 中偵測當前按下的方向鍵,並決定定位元素在視窗中的位置。其中元素的 offsetLeft 和 offsetTop 屬性可以存取它在頁面中的位置。

鍵盤響應順序

當按下鍵盤時,會連續觸發多個事件,它們將按如下順序發生。

對於字元鍵來說,鍵盤事件的響應順序:keydown → keypress → keyup。

對於非字元鍵(如功能鍵或特殊鍵)來說,鍵盤事件的相應順序:keydown → keyup。

如果按下字元鍵不放,則 keydown 和 keypress 事件將逐個持續發生,直至鬆開按鍵。

如果按下非字元鍵不放,則只有 keydown 事件持續發生,直至鬆開按鍵。

範例

下面設計一個簡單範例,以獲取鍵盤事件相應順序。
<textarea id="text" cols="26" rows="16"></textarea>
<script>
    var n = 1;  // 定義編號變數
    var text = document.getElementById("text");  // 獲取文字區域的參照指標
    text.onkeydown = f;  // 註冊keydown事件處理常式
    text.onkeyup = f;  // 註冊keyup事件處理常式
    text.onkeypress = f;  // 註冊keypress事件處理常式
    function f(e){  // 事件呼叫函數
        var e = e || window.event;  // 標準化事件物件
        text.value += (n++) + "=" + e.type +"  (keyCode=" + e.keyCode + ")n";
        //捕獲事件響應資訊
    }
</script>
演示效果如下:

當分別輸入 A、B、C 時: