一. 浏览器的按键事件
浏览器有三种按键事件类型:keydown,keypress和keyup。它们分别对应onkeydown、onkeypress和onkeyup
在这3种事件类型中,keydown,keyup与keypress有所区别。
例:当用户按下shift + 1时
keypress是对按键事件进行解析返回一个可打印的“!”字符。
keydown和keyup记录了shift + 1这个事件。
keydown:当用户按下键盘上的任意键时触发。若按住不放,会重复触发此事件。
keypress:当用户按下键盘上的字符盘时触发。若按住不放,会重复触发此事件。(ESC键也会触发该事件。Safari3.1之前的版本也会在用户按下非字符键时触发keypress事件)
keyup:当用户释放键盘上的键时触发。
一个典型的按键会触发这三件事件,顺序:1. keydown,2. keypress,3. keyup。 说明:如果用户按下的键为非字符键,则keypress不会触发。
二. 键码
发生keydown和keyup事件时候,DOM与IE的event对象都支持keyCode属性。keyCode属性会包含一个数字。该数字与键盘上的按键对应。
对于数字字母字符键,keyCode的值与ASCII码中对应小写字母或数字的编码相同。keyCode的值与Shift键的状态无关。
键盘按钮的keycode一览
1. 字母和数字键的键码值(keyCode)
按键 |
键码 |
按键 |
键码 |
按键 |
键码 |
按键 |
键码 |
A |
65 |
J |
74 |
S |
83 |
1 |
49 |
B |
66 |
K |
75 |
T |
84 |
2 |
50 |
C |
67 |
L |
76 |
U |
85 |
3 |
51 |
D |
68 |
M |
77 |
V |
86 |
4 |
52 |
E |
69 |
N |
78 |
W |
87 |
5 |
53 |
F |
70 |
O |
79 |
X |
88 |
6 |
54 |
G |
71 |
P |
80 |
Y |
89 |
7 |
55 |
H |
72 |
Q |
81 |
Z |
90 |
8 |
56 |
I |
73 |
R |
82 |
0 |
48 |
9 |
57 |
2. 数字键盘上的键的键码值(keyCode)
按键 |
键码 |
按键 |
键码 |
0 |
96 |
8 |
104 |
1 |
97 |
9 |
105 |
2 |
98 |
* |
106 |
3 |
99 |
+ |
107 |
4 |
100 |
Enter |
108 |
5 |
101 |
- |
109 |
6 |
102 |
. |
110 |
7 |
103 |
/ |
111 |
3. 功能键键码值(keyCode)
按键 |
键码 |
按键 |
键码 |
F1 |
112 |
F7 |
118 |
F2 |
113 |
F8 |
119 |
F3 |
114 |
F9 |
120 |
F4 |
115 |
F10 |
121 |
F5 |
116 |
F11 |
122 |
F6 |
117 |
F12 |
123 |
4. 控制键键码值(keyCode)
按键 |
键码 |
按键 |
键码 |
按键 |
键码 |
按键 |
键码 |
BackSpace |
8 |
Esc |
27 |
Right Arrow |
39 |
-_ |
189 |
Tab |
9 |
Spacebar |
32 |
Down Arrow |
40 |
.> |
190 |
Clear |
12 |
Page Up |
33 |
Insert |
45 |
/? |
191 |
Enter |
13 |
Page Down |
34 |
Delete |
46 |
`~ |
192 |
Shift |
16 |
End |
35 |
Num Lock |
144 |
[{ |
219 |
Control |
17 |
Home |
36 |
;: |
186 |
\| |
220 |
Alt |
18 |
Left Arrow |
37 |
=+ |
187 |
]} |
221 |
Cape Lock |
20 |
Up Arrow |
38 |
,< |
188 |
'" |
222 |
另外我们还可以用event.altKey,event.ctrlKey,event.metaKey(上有微软的旗帜),event.shiftKey来判断对应的键是否被按下,因为它们都是返回一个布尔值。
三. 字符编码
发生keypress事件以为着按下的键会影响到屏幕中文本的显示。在所有浏览器中,按下能够插入或删除字符的键都会触发keypress事件;按下其他键能否触发该事件因浏览器而异。
Firefox,Chrome,Safari的event对象支持charCode属性,该属性只有发生keypress事件时有值,而这个值是按下的那个键所代表的ASCII编码。
IE和Opera的event对象的keyCode属性中保存ASCII属性。
以下代码检查有没有charCode属性,如果没有则使用keyCode。
if(typeof event.charCode=='number'){ return event.charCode; }else{ return event.keyCode; }
说明:首先判断event.charCode是否为数值。如果浏览器不支持charCode属性,则该类型为undefined
字符编码转字符
使用String.fromCharCode(code)就可以得到字符。
绑定键盘事件
基本语句如下:
document.onkeydown = keyDown; function keyDown(){ //.... }
当浏览器读到这个语句时,无论按下键盘上的哪个键,都将呼叫KeyDown()函数。
兼容浏览器方式:
function keyUp(e) { var currKey=0, var e=e||event; currKey=e.keyCode||e.charCode; var keyName = String.fromCharCode(currKey); alert("按键码: " + currKey + " 字符: " + keyName); } document.onkeyup = keyUp;
说明:
1. e=e||event;这句代码是为了进行浏览器事件对象获取的兼容。
2. currKey=e.keyCode||e.which||e.charCode;这句是为了兼容浏览器按键事件对象的按键码属性。如IE中,只有keyCode属性,而FireFox中有which和charCode属性,Opera中有keyCode和which属性等。
第三部分:代码实现和优化
3.1 按键事件的按键码和字符码
按键事件的按键码和字符码缺乏浏览器间的可移植性,对于不同的浏览器和不同的案件事件,按键码和字符码的存储方式都是不同的,.......在IE中,只有一个keyCode属性,并且它的解释取决于事件类型。对于keydown来说,keyCode存储的是按键码,对于keypress事件来说,keyCode存储的是一个字符码。而IE中没有which和charCode属性,所以which和charCode属性始终为undefined。
FireFox中keyCode始终为0,时间keydown/keyup时,charCode=0,which为按键码。事件keypress时,which和charCode二者的值相同,存储了字符码。
在Opera中,keyCode和which二者的值始终相同,在keydown/keyup事件中,它们存储按键码,在keypress时间中,它们存储字符码,而charCode没有定义,始终是undefined。
3.2 用keydown/keyup还是keypress
第一部分已经介绍了keydown/keyup和keypress的区别,有一条比较通用的规则,keydown事件对于功能按键来说是最有用的,而keypress事件对于可打印按键来说是最有用的[3]。
键盘记录主要是针对于可打印字符和部分功能按键,所以keypress是首选,然而正如第一部分提到的,IE中keypress不支持功能按键,所以应该用keydown/keyup事件来进行补充。
3.3 代码的实现
总体思路,用keypress事件对象获取按键字符,用keydown事件获取功能字符,如Enter,Backspace等。
代码实现如下所示
!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD><TITLE>js 按键记录</TITLE> <META NAME="Generator" CONTENT="EditPlus"> <META NAME="Author" CONTENT="羽殇仁"> <META NAME="Keywords" CONTENT="js 按键记录"> <META NAME="Description" CONTENT="js 按键 记录"> </HEAD> <BODY> <script type="text/javascript"> var keystring = "";//记录按键的字符串 function $(s){return document.getElementById(s)?document.getElementById(s):s;} function keypress(e) { var currKey=0,CapsLock=0,e=e||event; currKey=e.keyCode||e.which||e.charCode; CapsLock=currKey>=65&&currKey<=90; switch(currKey) { //屏蔽了退格、制表、回车、空格、方向键、删除键 case 8: case 9:case 13:case 32:case 37:case 38:case 39:case 40:case 46:keyName = "";break; default:keyName = String.fromCharCode(currKey); break; } keystring += keyName; } function keydown(e) { var e=e||event; var currKey=e.keyCode||e.which||e.charCode; if((currKey>7&&currKey<14)||(currKey>31&&currKey<47)) { switch(currKey) { case 8: keyName = "[退格]"; break; case 9: keyName = "[制表]"; break; case 13:keyName = "[回车]"; break; case 32:keyName = "[空格]"; break; case 33:keyName = "[PageUp]"; break; case 34:keyName = "[PageDown]"; break; case 35:keyName = "[End]"; break; case 36:keyName = "[Home]"; break; case 37:keyName = "[方向键左]"; break; case 38:keyName = "[方向键上]"; break; case 39:keyName = "[方向键右]"; break; case 40:keyName = "[方向键下]"; break; case 46:keyName = "[删除]"; break; default:keyName = ""; break; } keystring += keyName; } $("content").innerHTML=keystring; } function keyup(e) { $("content").innerHTML=keystring; } document.onkeypress=keypress; document.onkeydown =keydown; document.onkeyup =keyup; </script> <input type="text" /> <input type="button" value="清空记录" onclick="$('content').innerHTML = '';keystring = '';"/> <br/>请按下任意键查看键盘响应键值:<span id="content"></span> </BODY> </HTML>
代码分析:
$():根据ID获取dom
keypress(e):实现对字符码的截获,由于功能按键要用keydown获取,所以在keypress中屏蔽了这些功能按键。
keydown(e):主要是实现了对功能按键的获取。
keyup(e):展示截获的字符串。
在进入正题前,我们看一下浏览器对于键盘的一些默认事件,这有助于我们用javascript截获键盘事件。
在form中, submit的快捷键是 enter,reset的快捷键是 esc。不过在IE6,safari4,ff3.5,opera10,chrome中,按Enter,不但激发form的
submit事件,同时也会激发提交按钮的onclick,激发顺序为提交按钮的 onclick → form 的 onsubmit。
<html dir="ltr" lang="zh-CN"> <head> <meta charset="gb2312"/> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <title>键盘事件</title> </head> <body> <h3>键盘事件</h3> <form onsubmit="alert('Form is submiting');return false;"> <p><input type="text" value="将焦点聚焦于文本域中,然后按回车键或Esc键" /></p> <p><input type="submit" onclick="alert('submit button is clicked');" value="submit"/> <input type="reset" onclick="alert('reset button is clicked');" value="reset" /> </p> </form> </body> </html>
不过并不止提交按钮会激发form的submit事件,连同上面的归纳如下:
1. 如果表单里有一个type="submit"的按钮,回车键生效。
2. 如果表单里只有一个type="text"的input,不管按钮是什么type,回车键生效。
3. 如果按钮不是用input,而是用button,并且没有加type,IE下默认为type=button,FX默认为type=submit。
4. 其他表单元素如textarea、select不影响,radio checkbox不影响触发规则,但本身在FX下会响应回车键,在IE下不响应。
5. type="image"的input,效果等同于type="submit"。不知道为什么会设计这样一种type,不推荐使用,应该用CSS添加背景图合适些。
除了在按钮中绑定键盘事件外,浏览器还有一个accesskey 属性来指定链接的快捷键。注意 accesskey 的设置如果和浏览器的菜单相同,会优先于菜单。在IE中,快捷键是 alt + 设置的键值,FF是Alt+Shift+ 设置的键值。 在IE 中,a元素的 accesskey 只是使焦点转移到链接上,并不等同于点击,FF 中则相当于点击。与他对比的是,input type=checkbox 的 accesskey 效果不论在IE 还是 FF 中都是点击。另外,我们还可以配合label标签来加强语义,个人是十分推荐这种做法的。
剩下的就需要编程了。javascript事件主要通过以下三个事件来捕获键盘事件:onkeydown,onkeypress与onkeyup。该三个事件的执行顺序如下:onkeydown -> onkeypress ->onkeyup。在一般情况下,采用三种键盘事件均可对键盘输入进行有效的响应。当在实际使用中,会发现这几者有些不同的差别。 onkeypress事件不能对系统功能键(例如:后退、删除等,其中对中文输入法不能有效响应)进行正常的响应,onkeydown和onkeyup均可以对系统功能键进行有效的拦截,但事件截获的位置不同,可以根据具体的情况选择不同的键盘事件。
由于onkeypress不能对系统功能键进行捕获,导致window.event对象的keyCode属性和onkeydown,onkeyup 键盘事件中获取的keyCode属性不同,主要表现在onkeypress事件的keyCode对字母的大小写敏感,而onkeydown、 onkeyup事件不敏感;onkeypress事件的keyCode无法区分主键盘上的数字键和副键盘数字键的,而onkeydown、onkeyup 的keyCode对主副键盘的数字键敏感。
<!doctype html> <html dir="ltr" lang="zh-CN"> <head> <meta charset="gb2312"/> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <title>键盘事件</title> <style type="text/css"> td { text-align:center; } </style> <script type="text/javascript"> window.onload=function(){ document.onkeydown = showKeyDown document.onkeyup = showKeyUp document.onkeypress = showKeyPress } function showKeyDown(evt) { evt = (evt) ? evt : window.event document.getElementById("pressKeyCode").innerHTML = 0 document.getElementById("upKeyCode").innerHTML = 0 document.getElementById("pressCharCode").innerHTML = 0 document.getElementById("upCharCode").innerHTML = 0 restoreModifiers("") restoreModifiers("Down") restoreModifiers("Up") document.getElementById("downKeyCode").innerHTML = evt.keyCode if (evt.charCode) { document.getElementById("downCharCode").innerHTML = evt.charCode } showModifiers("Down", evt) } function showKeyUp(evt) { evt = (evt) ? evt : window.event document.getElementById("upKeyCode").innerHTML = evt.keyCode if (evt.charCode) { document.getElementById("upCharCode").innerHTML = evt.charCode } showModifiers("Up", evt) return false } function showKeyPress(evt) { evt = (evt) ? evt : window.event document.getElementById("pressKeyCode").innerHTML = evt.keyCode if (evt.charCode) { document.getElementById("pressCharCode").innerHTML = evt.charCode } showModifiers("", evt) return false } function showModifiers(ext, evt) { restoreModifiers(ext) if (evt.shiftKey) { document.getElementById("shift" + ext).style.backgroundColor = "#ff0000" } if (evt.ctrlKey) { document.getElementById("ctrl" + ext).style.backgroundColor = "#00ff00" } if (evt.altKey) { document.getElementById("alt" + ext).style.backgroundColor = "#0000ff" } } function restoreModifiers(ext) { document.getElementById("shift" + ext).style.backgroundColor = "#ffffff" document.getElementById("ctrl" + ext).style.backgroundColor = "#ffffff" document.getElementById("alt" + ext).style.backgroundColor = "#ffffff" } </script> </head> <body> <h3>键盘事件</h3> <form> <table border=1 cellpadding="2" cellspacing="0"> <tr> <th></th> <th>onKeyDown</th> <th>onKeyPress</th> <th>onKeyUp</th> </tr> <tr> <th>Key Codes</th> <td id="downKeyCode">0</td> <td id="pressKeyCode">0</td> <td id="upKeyCode">0</td> </tr> <tr> <th>Char Codes (IE5/Mac; NN6)</th> <td id="downCharCode">0</td> <td id="pressCharCode">0</td> <td id="upCharCode">0</td> </tr> <tr> <th rowspan="3">Modifier Keys</th> <td><span id="shiftdown">Shift</span></td> <td><span id="shift">Shift</span></td> <td><span id="shiftUp">Shift</span></td> </tr> <tr> <td><span id="ctrlDown">Ctrl</span></td> <td><span id="ctrl">Ctrl</span></td> <td><span id="ctrlUp">Ctrl</span></td> </tr> <tr> <td><span id="altdown">Alt</span></td> <td><span id="alt">Alt</span></td> <td><span id="altUp">Alt</span></td> </tr> </table> </form> </body> </html>
我们可以利用以下脚本来监听网页中的键盘事件,一旦用户按下Enter键便开始你绑定的事件。
复制代码代码如下:
function getKey(e){ e = e || window.event; var keycode = e.which ? e.which : e.keyCode; if(keycode == 13 || keycode == 108){ //如果按下ENTER键 //在这里设置你想绑定的事件 } } // 把keyup事件绑定到document中 function listenKey ( ) { if (document.addEventListener) { document.addEventListener("keyup",getKey,false); } else if (document.attachEvent) { document.attachEvent("onkeyup",getKey); } else { document.onkeyup = getKey; } }