最近在开发一个在线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
分享到:
相关推荐
7. **UI库集成**:如果项目中已经使用了像Bootstrap、Material UI或React这样的前端框架,可以利用它们提供的工具栏组件,这样可以快速构建出符合设计风格的工具栏,并且利用框架自带的事件处理和状态管理机制。...
HTML 和 JavaScript 是构建网页交互性的重要工具,而键盘事件是实现用户与网页动态交互的关键环节。在本主题中,我们将深入探讨如何利用 HTML 和 JavaScript 实现对用户键盘输入的监听和处理。 首先,HTML 是超文本...
综上所述,这个项目通过JavaScript实现了跨浏览器的软键盘输入功能,对于理解和掌握前端交互、DOM操作、事件处理、兼容性问题解决等方面都有很好的实践意义。开发者可以根据自身项目需求,参考这个项目进行定制化...
标题提到的组件就是这样的一个工具,它允许开发者在React Native应用中捕获Android底层的键盘(或遥控器)事件。这个组件主要用于Android TV环境,目的是为了监听和处理遥控器产生的按键输入。 React Native是一种...
总的来说,Kibo为开发者提供了一种简单、灵活的方式来管理键盘事件,特别适合在JavaScript应用中实现基于键盘的交互。它的无依赖性、易用性和丰富的按键支持使得它成为处理键盘事件的实用工具。
在这个基于原生JavaScript实现的网页端2048游戏中,开发者充分利用了JavaScript的事件处理机制,使得游戏不仅可以在桌面浏览器上运行,同时也适配了移动端设备,为用户提供了一种跨平台的游戏体验。以下是对这个项目...
总的来说,`kibo`库为JavaScript开发者提供了一个强大的工具,帮助他们更轻松地管理和响应键盘事件,从而增强Web应用的用户交互体验。如果你在项目中遇到需要处理大量键盘交互的情况,`kibo`库无疑是一个值得考虑的...
在描述中,我们看到“全局键盘和鼠标侦听器”,这意味着开发者可以编写代码来捕捉系统范围内的键盘事件(如按键按下、释放)和鼠标事件(如点击、移动、滚动)。这对于创建跨平台的用户交互程序非常有用,因为它们能...
例如,Java中的`KeyListener`接口,Python的`Tkinter`库中的`bind`方法,JavaScript的`addEventListener`函数可以监听键盘事件,如`keydown`和`keyup`。 2. 事件处理函数:当键盘事件发生时,我们需要定义一个事件...
在这个场景中,我们讨论的是使用JavaScript来实现一个虚拟键盘,这对于触摸屏设备上的输入操作非常有用,比如在移动设备或平板电脑上,用户可能没有物理键盘,此时虚拟键盘就成为了必要的输入工具。 虚拟键盘的实现...
2. 输入管理:处理用户的键盘、鼠标和触摸输入,提供便捷的事件监听和响应机制。 3. 网络接口:可能包含WebSocket或其他协议的网络通信功能,支持实时多人在线游戏。 4. 时间和动画:提供时间管理和帧率控制,确保...
此外,Dreamweaver等工具提供了图形化的事件管理界面,如行为面板,使得开发者可以更直观地添加和管理事件。例如,调用JavaScript函数、改变元素属性、检查浏览器或插件类型、控制多媒体播放、拖动层以及跳转链接等...
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 ...
2. **事件处理**:利用addEventListener等方法,JavaScript可以监听用户的键盘输入、鼠标点击等事件,实现对视奏练习的实时响应。 3. **AJAX通信**:如果工具需要从服务器获取乐谱或用户数据,JavaScript可以通过...
例如,在"SkyPlane"游戏中,玩家可能通过键盘控制飞机移动,这就需要JavaScript监听键盘事件,并根据按键动作更新飞机的位置。 动画是游戏视觉效果的重要组成部分。在JavaScript中,可以使用requestAnimationFrame...
8. **项目构建**:`build.xml`和`project.xml`可能是指Apache Ant或Maven的构建文件,`ivy.xml`可能是Apache Ivy的依赖管理配置,这些都是Java项目常见的构建和依赖管理工具。这些工具可能会用到JavaScript编译或...
这通常需要结合CSS的过渡效果(transition)和关键帧动画(keyframe animation)来完成,而JavaScript则负责触发这些动画和管理状态。 另一方面,"制作页面小广告-素材"可能指的是在网页上显示浮动广告或弹窗广告。...
常见的事件有点击(click)、鼠标移动(mousemove)、键盘输入(keydown)等,通过addEventListener和removeEventListener方法添加和移除事件监听器。 4. **AJAX异步通信**:Asynchronous JavaScript and XML,虽然...