今天在重新看《javascript高级程序设计》的时候,当翻到关于事件的那章,那里讲述了键盘的几个事件(keydown,keyuup,keypress)以及IE跟其他主流浏览器在事件属性方面的异同,另一方面也想到了YUI中也有这么监听键盘事件功能的类,所以自己也就简单尝试去实现另外一种操作方式的类:KeyEvent。示例如下:
var Event = {
type: "keydown",
data: {
name: "Supersha"
}
}
onload = function(){
//表示需要同时按下shift、ctrl以及1键keydown事件程序才会生效。
var key = new KeyEvent([49],{"shiftKey":true,"ctrlKey":true});
key.keydown(function(e){
alert(e.keyCode);
});
var key2 = new KeyEvent([50]);
key2.keydown(function(e){
alert(this.data.name);
}, Event);
}
可以同时声明几个监听键盘事件的实例对象,互不干扰。上面的示例说明了keydown的使用方法,keyup和keypress也是类似的。《测试页面》
下面是KeyEvent类的源码:
var KeyEvent = function(aKeyCode, oFlag){
this.keyCodes = aKeyCode || [];
this.key = oFlag || {};
}
KeyEvent.prototype._addListener = function(elem, type, handle, context){
var that = this;
var _handle = function(e){
e = e || window.event;
var codeFlag = true;
var keyFlag = true;
//检查参数指明的keyCode有没有按下
for (var i = 0, l = that.keyCodes.length; i < l; i++) {
if (e.keyCode !== that.keyCodes[i]) {
codeFlag = false;
}
}
//检查参数指明的ctrl,shift,alt键是否按下。
for (var k in that.key) {
if (!e[k]) {
keyFlag = false;
}
}
if (keyFlag && codeFlag) {
handle.call(context || elem, e);
}
}
if (elem.addEventListener) {
elem.addEventListener(type, _handle, false);
}
else if (elem.attachEvent) {
elem.attachEvent("on" + type, _handle);
}
else {
elem["on" + type] = _handle;
}
}
//context是handle函数内this的上下文,不指明的话默认是当前的DOM元素(document)
KeyEvent.prototype.keydown = function(handle, context){
this._addListener(document, "keydown", handle, context);
}
KeyEvent.prototype.keyup = function(handle, context){
this._addListener(document, "keyup", handle, context);
}
KeyEvent.prototype.keypress = function(handle, context){
this._addListener(document, "keypress", handle, context);
}
//////////////////// 2010-01-24 Update /////////////////////
由于考虑到键盘keyCode难以记忆,所以使得通过keyCode编码来触发key event的时候有些不方便。基于这一点,我重新修改了一下KeyEvent类的实现方式,提供了直接写数字键和字母键支持,比如:
var key=new KeyEvent(["a","5"],{"shiftKey":true,"ctrlKey":true});
key.keydown(function(e)){
alert("you keydown 'a');
}
在源码里只是修改了KeyEvent构造函数而已,其他不变:
var KeyEvent = function(aKeyCode, oFlag){
this.keyCodes = [];
//由于本人还没有了解到字符键跟对应的键盘的keyCode直接转换的javascript内置函数,只能使用这种方式。
var codes_swidth={"a":65,"b":66,"c":67,"d":68,"e":69,"f":70,"g":71,"h":72,"i":73,"j":74,"k":75,
"l":76,"m":77,"n":78,"o":79,"p":80,"q":81,"r":82,"s":83,"t":84,"u":85,
"v":86,"w":87,"x":88,"y":89,"z":90}
for(var i=0,l=aKeyCode.length;i<l;i++){
this.keyCodes[i]=typeof aKeyCode[i] === "string" ? codes_swidth[aKeyCode[i]] || aKeyCode[i].charCodeAt(0) : aKeyCode[i];
}
this.key = oFlag || {};
}