最近在开发一个在线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
分享到:
相关推荐
10.5.2 键盘事件 286 10.5.3 表单事件 291 10.5.4 编辑事件 295 10.5.5 页面事件 297 第11章 使用Cookie和文件 303 11.1 Cookie 303 11.1.1 Cookie概述 303 11.1.2 Cookie属性 305 11.1.3 创建Cookie 305 11.1.4 ...
10.5.2 键盘事件 10.5.3 表单事件 10.5.4 编辑事件 10.5.5 页面事件 第11章 使用Cookie和文件 11.1 Cookie 11.1.1 Cookie概述 11.1.2 Cookie属性 11.1.3 创建Cookie 11.1.4 读取Cookie 11.1.5 ...
17.9 键盘事件 第18章 脚本化HTTP 18.1 使用XMLHttpRequest 18.2 借助发送HTTP请求:JSONP 18.3 基于服务器端推送事件的Comet技术 第19章 jQuery类库 19.1 jQuery基础 19.2 jQuery的getter和setter 19.3 修改文档...
17.9 键盘事件 第18章 脚本化HTTP 18.1 使用XMLHttpRequest 18.2 借助发送HTTP请求:JSONP 18.3 基于服务器端推送事件的Comet技术 第19章 jQuery类库 19.1 jQuery基础 19.2 jQuery的getter和setter 19.3 修改文档...
17.9 键盘事件 478 第18章 脚本化http 484 18.1 使用xmlhttprequest 487 18.2 借助[script]发送http请求:jsonp 505 18.3 基于服务器端推送事件的comet技术 508 第19章 jquery类库 514 19.1 jquery基础 515 19.2 ...
17.9 键盘事件 478 第18章 脚本化http 484 18.1 使用xmlhttprequest 487 18.2 借助[script]发送http请求:jsonp 505 18.3 基于服务器端推送事件的comet技术 508 第19章 jquery类库 514 19.1 jquery基础 515 19.2 ...
17.9 键盘事件 第18章 脚本化HTTP 18.1 使用XMLHttpRequest 18.2 借助发送HTTP请求:JSONP 18.3 基于服务器端推送事件的Comet技术 第19章 jQuery类库 19.1 jQuery基础 19.2 jQuery的getter和setter 19.3 修改文档...
17.9 键盘事件 478 第18章 脚本化http 484 18.1 使用xmlhttprequest 487 18.2 借助[script]发送http请求:jsonp 505 18.3 基于服务器端推送事件的comet技术 508 第19章 jquery类库 514 19.1 jquery基础 515 19.2 ...
6.5 高级事件管理 178 6.6 教程:一页的FAQ 180 6.6.1 任务概览 180 6.6.2 编程 180 第7章 改进图像 184 7.1 交换图像 184 7.1.1 改变图像的src属性 184 7.1.2 预载入图像 186 7.1.3 翻滚图像 187 7.2 教程:添加...
开发人员和设计师的浏览器 :school: Academy-交互式React和GraphQL研讨会 :love_letter: 用于Twitter DM和Twitter的独立应用程序UI :hammer_and_wrench: 用于可视化组织,创建和管理JavaScript项目的工具。...
如果您喜欢用JavaScript编写自己的窗口或应用程序管理工具包的想法,Phoenix可能会为您提供所需的东西。 使用Phoenix,您可以绑定键盘快捷键和系统事件,并使用它们与macOS进行交互。 当前版本:2.6.6( ) 要求:...
打开 菜单 --> 工具 --> 宏(Macro) --> 宏资源管理器(Macro Explorer) ,在Explorer中选择新建的工程,修改Module名(右键),在Module名上双击,在打开的Macro IDE中进行编辑。 3. 在Module下,添加要实现的...
1、(1)从控制面板-管理工具里打开IIS,将主目录设置为自己建的文件夹; (2)启动DW,新建站点,选择ASP服务器技术; (3)在DW的代码视图下编写脚本程序; (4)使用预览功能运行脚本程序。 2、提示: (1)使用...
本书共分17章,分别介绍了JavaScript的对象编程、JavaScript浏览器对象模型和事件机制、ExtJS的核心类库和组件、ExtJS的事件处理方式、设计进度条、设计工具栏和菜单栏、设计面板、设计表格、设计表单、设计数据表、...
本书共分17章,分别介绍了JavaScript的对象编程、JavaScript浏览器对象模型和事件机制、ExtJS的核心类库和组件、ExtJS的事件处理方式、设计进度条、设计工具栏和菜单栏、设计面板、设计表格、设计表单、设计数据表、...
Dash for mac是使用与Mac OS平台的软件编程文档管理工具,可以浏览API文档,以及管理代码片段工具。Dash自带了丰富的API文档,涉及各种主流的编程语言和框架。 可以浏览API文档,以及管理代码片段工具。Dash自带了...
AccDC是可伸缩,跨浏览器和跨平台兼容的动态内容管理系统,可自动呈现动态内容,以确保仅屏幕阅读器和键盘用户的可访问性。 在皇家艺术协会的支持下,AccDC获得了美国劳工部的“无障碍获取奖”,并在2012年由美国...