JavaScript 跨浏览器键盘事件处理与兼容实现

作者:像素猫

时间:2026-10-27

浏览:149

本文详解 JavaScript 中 keydown、keypress 和 keyup 三种键盘事件的机制与差异,重点解决 IE、Firefox 和 Opera 等浏览器在事件对象获取及按键码属性上的兼容性问题。通过对比 navigator.appName 判断与 e=e||event 技巧,提供完整的跨浏览器按键记录代码实现,涵盖功能键与字符键的完整捕获逻辑。

文章目录

浏览器按键事件机制

第一部分:浏览器的按键事件

在 JavaScript 中实现键盘记录功能,需要重点关注浏览器的三种按键事件类型:keydown、keypress 和 keyup,它们分别对应 onkeydown、onkeypress 和 onkeyup 这三个事件处理程序。一次完整的按键操作通常会依次触发这三种事件:首先是按下时的 keydown,接着是按键过程中的 keypress,最后是按键释放时的 keyup。

在这三种事件类型中,keydown 和 keyup 属于底层事件,而 keypress 属于较高级的事件。所谓“高级”,是指 keypress 会对按键事件进行解析,返回一个可打印的字符。例如,当用户按下 Shift + 1 时,keypress 事件会返回“!”字符,而 keydown 和 keyup 仅记录 Shift + 1 这一组合事件本身。[1]

需要注意的是,keypress 仅对可打印字符有效。对于功能键(如 F1-F12、Backspace、Enter、Escape、PageUp、PageDown 和方向键等),标准浏览器不会触发 keypress 事件,但会触发 keydown 和 keyup 事件。不过,在 Firefox 浏览器中,功能键也可以产生 keypress 事件。

传递给 keydown、keypress 和 keyup 事件处理程序的事件对象包含一些通用属性。如果按下按键时同时按下了 Alt、Ctrl 或 Shift 键,可以通过事件对象的 altKey、ctrlKey 和 shiftKey 属性来获取这些修饰键的状态。这些属性在 Firefox 和 IE 浏览器中是通用的。

跨浏览器兼容处理

第二部分:兼容浏览器

涉及浏览器操作的 JavaScript 代码都必须考虑浏览器兼容性问题。目前常用的浏览器主要基于两大内核:IE 内核和 Mozilla 内核。Maxthon(傲游)基于 IE 内核,而 Firefox 和 Opera 基于 Mozilla 内核。

2.1 事件的初始化

首先需要了解如何初始化该事件,基本语句如下:

function keyDown(){} document.onkeydown = keyDown;

当浏览器执行到上述语句时,无论按下键盘上的哪个键,都将调用 keyDown() 函数。

2.2 FireFox 和 Opera 的实现方法

Firefox 和 Opera 等浏览器的实现方式比 IE 复杂,因此这里先进行描述。

keyDown() 函数有一个隐藏的参数,通常用字母“e”来表示这个变量。

function keyDown(e)

变量 e 表示发生击键事件,要确定按下了哪个键,需要使用 which 属性:

e.which

e.which 将给出该键的索引值。要将索引值转换为对应的字母或数字字符,需要用到静态函数 String.fromCharCode(),如下所示:

String.fromCharCode(e.which)

将上述语句组合起来,我们可以在 Firefox 中获取被按下的键:

代码如下:

function keyDown(e) {
var keycode = e.which;
var realkey = String.fromCharCode(e.which);
alert("按键码: " + keycode + " 字符: " + realkey);
   } 
document.onkeydown = keyDown;

2.3 IE 的实现方法

IE 浏览器不需要 e 变量,而是使用 window.event.keyCode 来替代 e.which。将键的索引值转化为真实键值的方法类似:String.fromCharCode(event.keyCode),程序如下:

代码如下:

function keyDown() {
var keycode = event.keyCode;
var realkey = String.fromCharCode(event.keyCode);
alert("按键码: " + keycode + " 字符: " + realkey);
   } 
document.onkeydown = keyDown;

2.4 判断浏览器类型

了解了在不同浏览器中获取按键事件对象的方法后,接下来需要判断浏览器类型。判断方法有多种,包括直观易懂的和巧妙实现的。这里介绍一种通用方法:利用 navigator 对象的 appName 属性(也可以使用 userAgent 属性)。这里使用 appName 来判断浏览器类型:IE 和 Maxthon 的 appName 为“Microsoft Internet Explorer”,而 Firefox 和 Opera 的 appName 为“Netscape”。因此,一个功能较简单的代码如下:

代码如下:

function keyUp(e) {
if(navigator.appName == "Microsoft Internet Explorer")
      { 
var keycode = event.keyCode;
var realkey = String.fromCharCode(event.keyCode);
}else
      { 
var keycode = e.which;
var realkey = String.fromCharCode(e.which);
      } 
alert("按键码: " + keycode + " 字符: " + realkey);
    } 
document.onkeyup = keyUp;

另一种比较简洁的方法[2]:


代码如下:

function keyUp(e) {
var currKey=0,e=e||event;
currKey=e.keyCode||e.which||e.charCode;
var keyName = String.fromCharCode(currKey);
alert("按键码: " + currKey + " 字符: " + keyName);
   } 
document.onkeyup = keyUp;

上述方法较为巧妙,简要解释如下:


首先,e=e||event; 这句代码用于兼容不同浏览器的事件对象获取方式。其含义是:如果在 Firefox 或 Opera 中,隐藏变量 e 存在,则 e||event 返回 e;如果在 IE 中,隐藏变量 e 不存在,则返回 event。


其次,currKey=e.keyCode||e.which||e.charCode; 这句代码用于兼容不同浏览器按键事件对象的按键码属性(详见第三部分)。例如,IE 中只有 keyCode 属性,而 Firefox 中有 which 和 charCode 属性,Opera 中有 keyCode 和 which 属性等。

上述代码仅实现了浏览器兼容和 keyup 事件对象的获取,简单弹出了按键码和字符。但问题出现了:当按下字符键时,字符总是大写的;而按下 Shift 键时,显示的字符很奇怪。因此,需要进一步优化代码。

按键码兼容与代码优化

第三部分:代码实现和优化

3.1 按键事件的按键码和字符码

按键事件的按键码和字符码缺乏浏览器间的可移植性。对于不同的浏览器和不同的按键事件,按键码和字符码的存储方式各不相同。在 IE 中,只有一个 keyCode 属性,且其解释取决于事件类型。对于 keydown 事件,keyCode 存储的是按键码;对于 keypress 事件,keyCode 存储的是字符码。IE 中没有 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):展示截获的字符串。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章