javascript键盘事件管理工具

最近在开发一个在线IDE。
在线IDE其中很重要的一个难点是如何处理好快捷键的事件绑定
针对这个问题我写了一个库来管理快捷键事件:
比如按下alt+/ 提示代码
ctrl+enter 执行代码
ctrl+d 删除一行代码

lib.js类库代码如下:

var lib = (function() {
var addListener = function(element, eventType, func, args) {
var eventHandler = func;
if (args) {
eventHandler = function(e) {
func.call(this, e, args);
}
}
if (element.addEventListener) {
element.addEventListener(eventType, eventHandler, false);
} else if (ele.attachEvent) {
element.attachEvent('on' + eventType, eventHandler);
} else {
element['on' + eventType] = eventHandler;
}
};
var toString = Object.prototype.toString, class2type;
var type = function(obj) {
if (!class2type) {
var class2type = {}, arr = "Boolean Number String Function Array Date RegExp Object"
.split(" ");
while (arr.length > 0) {
var name = arr.pop();
class2type["[object " + name + "]"] = name.toLowerCase();
}
}
return obj == null ? String(obj) : class2type[toString.call(obj)]
|| "object";
};
var shift_nums = {
"`" : "~",
"1" : "!",
"2" : "@",
"3" : "#",
"4" : "$",
"5" : "%",
"6" : "^",
"7" : "&",
"8" : "*",
"9" : "(",
"0" : ")",
"-" : "_",
"=" : "+",
";" : ":",
"'" : "\"",
"," : "<",
"." : ">",
"/" : "?",
"\\" : "|"
}, number_keys = {
"`" : 192,
"1" : 49,
"2" : 50,
"3" : 51,
"4" : 52,
"5" : 53,
"6" : 54,
"7" : 55,
"8" : 56,
"9" : 57,
"0" : 48,
"-" : 189,
"=" : 187,
";" : 186,
"'" : 222,
"\"" : 16,
"," : 188,
"." : 190,
"/" : 191,
"\\" : 220
},
// Special Keys - and their codes
special_keys = {
'esc' : 27,
'escape' : 27,
'tab' : 9,
'space' : 32,
'return' : 13,
'enter' : 13,
'backspace' : 8,

'scrolllock' : 145,
'scroll_lock' : 145,
'scroll' : 145,
'capslock' : 20,
'caps_lock' : 20,
'caps' : 20,
'numlock' : 144,
'num_lock' : 144,
'num' : 144,

'pause' : 19,
'break' : 19,

'insert' : 45,
'home' : 36,
'delete' : 46,
'end' : 35,

'pageup' : 33,
'page_up' : 33,
'pu' : 33,

'pagedown' : 34,
'page_down' : 34,
'pd' : 34,

'left' : 37,
'up' : 38,
'right' : 39,
'down' : 40,

'f1' : 112,
'f2' : 113,
'f3' : 114,
'f4' : 115,
'f5' : 116,
'f6' : 117,
'f7' : 118,
'f8' : 119,
'f9' : 120,
'f10' : 121,
'f11' : 122,
'f12' : 123
};

var adaptor = function(e, key_combination, callback) {
if (e.keyCode)
code = e.keyCode;
else if (e.which)
code = e.which;
var character = String.fromCharCode(code).toLowerCase();
var keys = key_combination.split("+");
var kp = 0;
var modifiers = {};
modifiers.ctrl = true, modifiers.shift = true, modifiers.alt = true;
if (e.ctrlKey)
modifiers.ctrl = false;
if (e.shiftKey)
modifiers.shift = false;
if (e.altKey)
modifiers.alt = false;

for (var i = 0, len = keys.length;k = keys[i], i < len; i++) {
// Modifiers
if (k == 'ctrl' || k == 'control') {
kp++;
modifiers.ctrl = !modifiers.ctrl;
} else if (k == 'shift') {
kp++;
modifiers.shift = !modifiers.shift;
} else if (k == 'alt') {
kp++;
modifiers.alt = !modifiers.alt;
} else if (special_keys[k] == code) {
kp++;
} else if (character == k) {
kp++;
} else if (number_keys[k] == code) {
kp++;
} else {
if (shift_nums[character] && e.shiftKey) {
character = shift_nums[character];
if (character == k)
kp++;
}
}
}
if (kp == keys.length && modifiers.ctrl && modifiers.shift
&& modifiers.alt) {
if (callback) {
callback(e);
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
}
return true;
}
};
var splitCombination = function(e, key_combination, callback) {
var keys = key_combination.split("|");
for (var i = 0;i < keys.length; i++) {
if (adaptor(e, keys[i], callback)) {
return true;
}
}
};
var handler = function(evt, opt) {
var funcs = opt["funcs"], publicHandler = opt["commonHandler"];;
for (var i = 0;i < funcs.length; i++) {
var func = funcs[i];
var k = func["keyComb"], h = func["handler"], doit = func["docommon"];
if (splitCombination(evt, k)) {
var stop = func["stop"], prevent = func["prevent"];
h.call(this, evt, k);
if (stop && evt.stopPropagation) {
evt.stopPropagation();
}
if (prevent && evt.preventDefault) {
evt.preventDefault();
}
if (publicHandler && doit) {
publicHandler.call(this, evt,func);
}
break;
}
}
};
var handlerEvent = function(evt, args) {
switch (evt.type) {
case "keydown" :
handler(evt, args);
break;
case 'keypress' :
handler(evt, args);
break;
case 'keyup' :
handler(evt, args);
break;
}
// evt.preventDefault();
};
/**
* @param element
* 被注册事件页面元素
* @param eventType
* 事件类型 eg:click、keyup
* @param opt
* 事件处理的回调函数、或者是一个特定的事件对象数组
* [{keyComb:"alt+/",handler:func,stop:false}]
*/
var register = function(element, eventType, opt) {
if (type(opt) === 'function') {
addListener(element, eventType, opt);
} else if (type(opt) === 'object') {
addListener(element, eventType, handlerEvent, opt);
}
};
return {
register : register
}
}());



测试页面代码如下;

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>MyHtml.html</title>

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style type="text/css">
body {
margin: 30px;
line-height: 16px;
}
</style>
<script type="text/javascript" src="lib.js"></script>
<script type="text/javascript" src="libtest.js"></script>
</head>

<body>
<pre contenteditable="true">22</pre>
</body>
</html>


libtest.js

window.addEventListener('load', function() {
var pre = document.getElementsByTagName("pre")[0];
// lib.register(pre,"click",function(){alert("pre")});
var handler = function(e, k) {
console.log(k);
};
var commonHandler = function() {
console.log("execute commonHandler");
};
var keydown_opt = {
funcs : [ {
keyComb : "alt+/",
handler : handler
}, {
keyComb : "ctrl+s",
handler : handler,
stop : true,
prevent : true
}, {
keyComb : "tab",
handler : handler,
stop : true,
prevent : false
}, {
keyComb : "a|b|c|d|'",
handler : handler,
stop : true,
prevent : false
}]
};
//当需要捕获类似于{ "这样的字符的时候 需要加上shift
var keypress_opt = {
commonHandler : commonHandler,
funcs : [{
keyComb : "shift+{|shift+\"",
handler : handler,
stop : true,
prevent : false,
docommon : true
}]
};
lib.register(pre, "keydown", keydown_opt);
lib.register(pre, "keypress", keypress_opt);
}, true);


监听键盘按下事件配置项
配置项有两个参数:
funcs:array
一个对象数组,数组中每个对象对应着一个快捷键处理对象keyCombHandler
commonHandler:function
公共的回调函数, 所有按键都可能回触发的回调函数,
如果keyCombHandler对象中的docommon设置为true则keyCombHandler会执行该回调函数

快捷键处理对象:
keyCombHandler:Object
快捷键处理对象,每个快捷键对应一个对象、该对象可以配置十分取消默认的行为、是否阻止事件冒泡等。请参照下面的属性
配置属性
keyComb:String
组合快捷键 比如alt+/或 a|b|c|d (|表示或 +表示与)
handler:function
按下相应的快捷键后触发的处理函数
stop:boolean
是否阻止事件冒泡 默认false
prevent:boolean
是否取消默认的事件 默认false
docommon:boolean
是否执行公共的回调函数 默认false
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值