深刻理解DOM事件類型系列第二篇——鍵盤事件

前面的話

  鼠標和鍵盤是電腦端主要的輸入設備,上篇介紹了鼠標事件,本文將詳細介紹鍵盤事件html

 

類型

  鍵盤事件用來描述鍵盤行爲,主要有keydown、keypress、keyup三個事件web

keydownchrome

  當用戶按下鍵盤上的任意鍵時觸發,若是按住不放的話,會重複觸發該事件瀏覽器

<div id="test" style="height: 30px;width: 200px;background-color: pink;">請按下鍵盤上的任意鍵</div>
<button id="reset">還原</button>
<script>
reset.onclick = function(){history.go();}
document.onkeydown = function(e){
    if(!test.mark){
        test.innerHTML ='';
    }
    test.mark = 1;
    e = e || event;
    test.innerHTML += e.type;
}
</script>

keypress編碼

  當用戶按下鍵盤上的字符鍵時觸發,按下功能鍵時不觸發。若是按住不放的話,會重複觸發該事件spa

  [注意]關於esc鍵,各瀏覽器處理不一致。IE瀏覽器和firefox瀏覽器按下esc鍵時,會觸發keypress事件;而chrome/safari/opera這三個webkit內核的瀏覽器則不會觸發firefox

  鍵盤事件必須綁定在能夠得到焦點的元素上。而頁面剛加載完成時,焦點處於document元素code

  [注意]IE瀏覽器不徹底支持綁定在document元素上的keypress事件,只有IE9+瀏覽器在使用DOM2級事件處理程序時才支持htm

  因此,如下代碼中,只有焦點處於id爲'test'的元素上,纔會發生keypress事件對象

<button id="test" style="height: 30px;width: 200px;background-color: pink;">請按下鍵盤上的任意鍵</button><br>
<button id="reset">還原</button>
<script>
reset.onclick = function(){history.go();}
test.focus();
test.onkeypress = function(e){
    if(!test.mark){
        test.innerHTML ='';
    }
    test.mark = 1;
    e = e || event;
    test.innerHTML += e.type;
}
</script>

keyup

  當用戶釋放鍵盤上的鍵時觸發

<div id="test" style="height: 30px;width: 200px;background-color: pink;">請按下鍵盤上的任意鍵</div>
<button id="reset">還原</button>
<script>
reset.onclick = function(){history.go();}
document.onkeyup = function(e){
    if(!test.mark){
        test.innerHTML ='';
    }
    test.mark = 1;
    e = e || event;
    test.innerHTML += e.type;
}
</script>

時間間隔

  系統爲了防止按鍵誤被連續按下,因此在第一次觸發keydown事件後,有500ms的延遲,纔會觸發第二次keydown事件

  [注意]相似的,keypress事件也存在500ms的時間間隔

<button id="btn">獲取間隔時間</button>
<span>說明:按鈕獲取焦點後,使用空格鍵按下一段時間,鬆開後可獲取keydown事件的時間間隔</span>
<div id="result"></div>
<script>
var time = [];
var last=0;
btn.onkeydown = function(e){
    e = e || event;
    time.push(e.timeStamp-last);
    last = e.timeStamp;
}
btn.onclick = function(){
    time.shift();
    result.innerHTML = time.join();
}
</script>

順序

  若是用戶一直按鍵不鬆開,就會連續觸發鍵盤事件,觸發的順序以下

一、keydown
二、keypress
三、keydown
四、keypress
五、(重複以上過程)
六、keyup
<button id="test" style="height: 30px;width: 200px;background-color: pink;">請按下鍵盤上的任意鍵</button><br>
<button id="reset">還原</button>
<script>
reset.onclick = function(){history.go();}
test.focus();
test.onkeypress =test.onkeydown =test.onkeyup = function(e){
    if(!test.mark){
        test.innerHTML ='';
    }
    test.mark = 1;
    e = e || event;
    test.innerHTML += e.type + ';';
}
</script>

按鍵信息

  鍵盤事件包括keyCode、key、char、keyIdentifier和修改鍵共5個按鍵信息

鍵碼keyCode

  在發生鍵盤事件時,event事件對象的鍵碼keyCode屬性中會包含一個代碼,與鍵盤上一個特定的鍵對應。對數字字母字符鍵,keyCode屬性的值與ASCII碼中對應大寫字母或數字的編碼相同

  [注意]firfox瀏覽器不支持keypress事件中的keyCode屬性

  而咱們在作遊戲時,經常使用的四個方向按鍵,左上右下(順時針)的鍵碼分別是3七、3八、3九、40

<div id="test" style="height: 30px;width: 200px;background-color: pink;"></div>
<button id="reset">還原</button>
<script>
reset.onclick = function(){history.go();}
document.onkeyup = function(e){
    e = e || event;
    test.innerHTML += e.keyCode + ';';
}
</script>

key

  key屬性是爲了取代keyCode而新增的,它的值是一個字符串。在按下某個字符鍵時,key的值就是相應的文本字符;在按下非字符鍵時,key的值是相應鍵的名,默認爲空字符串

  [注意]IE8-瀏覽器不支持,而safari瀏覽器不支持keypress事件中的key屬性

<div id="test" style="height: 30px;width: 200px;background-color: pink;"></div>
<button id="reset">還原</button>
<script>
reset.onclick = function(){history.go();}
document.onkeyup = function(e){
    e = e || event;
    test.innerHTML = e.key;
}
</script>

char

  char屬性在按下字符鍵時的行爲與key相同,但在按下非字符鍵時值爲null

  [注意]該屬性只有IE9+瀏覽器支持

keyIdentifier

  keyIdentifier屬性在按下非字符鍵的狀況下與key的值相同。對於字符鍵,keyIdentifier返回一個格式相似「U+0000」的字符串,表示Unicode值

  [注意]該屬性只有chrome/safari/opera瀏覽器支持

<div id="test" style="height: 30px;width: 200px;background-color: pink;"></div>
<button id="reset">還原</button>
<script>
reset.onclick = function(){history.go();}
document.onkeyup = function(e){
    e = e || event;
    test.innerHTML = e.keyIdentifier;
}
</script>

兼容

  通常地,使用key屬性和keyCode屬性來實現兼容處理。key屬性IE8-瀏覽器不支持,而keyCode屬性沒法區分大小寫字母

var handler = function(e){
    var CompatibleKey;
    e = e || event;
    //支持key屬性
    if(e.key != undefined){
        CompatibleKey = e.key;
    }else{
        //當按鍵是數字或大寫字母時
        if(e.keyCode>47 && e.keyCode<58 || e.keyCode>64 && e.keyCode<91){
            CompatibleKey =String.fromCharCode(e.keyCode);
        }else{
            //當案按鍵是方向按鍵時
            switch(e.keyCode){
                case 37:
                    CompatibleKey = 'ArrowLeft';
                    break;
                case 38:
                    CompatibleKey = 'ArrowUp';
                    break;
                case 39:
                    CompatibleKey = 'ArrowRight';
                    break;
                case 40:
                    CompatibleKey = 'ArrowDown';
                    break;
            }
        }    
    }
}

修改鍵

  修改鍵在鼠標事件中介紹過,在鍵盤事件中也存在修改鍵

  修改鍵就是Shift、Ctrl、Alt和Meta(在Windows鍵盤中是Windows鍵,在蘋果機中是Cmd鍵)。DOM爲此規定了4個屬性,表示這些修改鍵的狀態:shiftKey、ctrlKey、altKey和metaKey。這些屬性中包含的都是布爾值,若是相應的鍵被按下了,則值爲true;不然值爲false

<div id="box" style="height:30px;width:300px;background:pink;"></div>
<script>
document.onkeyup=function(e){
    e = e || event;
       if(e.shiftKey){box.innerHTML = 'shiftKey;'}
       if(e.ctrlKey){box.innerHTML = 'ctrlKey;'}
       if(e.altKey){box.innerHTML = 'altKey;'}
       if(e.metaKey){box.innerHTML = 'metaKey;'}
}
document.onkeydown = function(){
    return false;
}
</script>

應用

【1】提示大寫

  在輸入框中輸入字符時,若是大寫模式開啓,提示此時爲大寫模式。提示大寫並非說當前輸出的是大寫字母,而是說當前caps lock大寫按鍵被按下

  [注意]大寫有兩種實現方式:一種是在capslock開啓的狀況下,另外一種是輸入字符時,同時按下shift鍵

<input id="test">
<span id="tips"></span>
<script>
test.onkeydown = function(e){
    e = e || event;
    //兼容IE8-瀏覽器,由於IE8-瀏覽器不支持在定時器中傳遞事件對象e
    var shiftKey = e.shiftKey;
    var keyCode = e.keyCode;
    //經過定時器延遲來獲取當前輸入字符值
    setTimeout(function(){
        var value = test.value.slice(-1);
        //若是沒有按下shift鍵,而且當前爲大寫字母,或者按下shift鍵,且當前爲小寫字母
        if(!shiftKey && /[A-Z]/.test(value) || shiftKey && /[a-z]/.test(value)){
            tips.innerHTML = '當前爲大寫模式';
            setTimeout(function(){
                tips.innerHTML = '';
            },400)
        }                
    })
}
</script>

【2】過濾輸入

  只能輸入數字,輸入其餘字符沒有效果

<input id="test">
<span id="tips">只能輸入數字</span>
<script>
test.onkeydown = function(e){
    e = e || event;
    //利用定時器,獲取實時輸入值
    setTimeout(function(){
        //當輸入值中包含非數字時
        if(/[^0-9]/.test(test.value)){
            //只輸出數字值
            test.value = String(/\d*/.exec(test.value));
        }
    })
}
</script>
相關文章
相關標籤/搜索