JavaScript:键盘事件

一. 浏览器的按键事件 

浏览器有三种按键事件类型:keydownkeypresskeyup。它们分别对应onkeydownonkeypressonkeyup

 

在这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; 
} 
} 
 

 

 

 

 

 

 

 

你可能感兴趣的:(JavaScript)