`
goodscript
  • 浏览: 72918 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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 
分享到:
评论

相关推荐

    javascript控件开发之工具栏控件

    7. **UI库集成**:如果项目中已经使用了像Bootstrap、Material UI或React这样的前端框架,可以利用它们提供的工具栏组件,这样可以快速构建出符合设计风格的工具栏,并且利用框架自带的事件处理和状态管理机制。...

    html.rar_html javascript_键盘

    HTML 和 JavaScript 是构建网页交互性的重要工具,而键盘事件是实现用户与网页动态交互的关键环节。在本主题中,我们将深入探讨如何利用 HTML 和 JavaScript 实现对用户键盘输入的监听和处理。 首先,HTML 是超文本...

    javascript实现软键盘输入,兼容多种浏览器,测试通过

    综上所述,这个项目通过JavaScript实现了跨浏览器的软键盘输入功能,对于理解和掌握前端交互、DOM操作、事件处理、兼容性问题解决等方面都有很好的实践意义。开发者可以根据自身项目需求,参考这个项目进行定制化...

    该组件用于ReactNative中获取Android原生层面的键盘响应事件

    标题提到的组件就是这样的一个工具,它允许开发者在React Native应用中捕获Android底层的键盘(或遥控器)事件。这个组件主要用于Android TV环境,目的是为了监听和处理遥控器产生的按键输入。 React Native是一种...

    Kibo 用于处理键盘事件的Javascript工具库

    总的来说,Kibo为开发者提供了一种简单、灵活的方式来管理键盘事件,特别适合在JavaScript应用中实现基于键盘的交互。它的无依赖性、易用性和丰富的按键支持使得它成为处理键盘事件的实用工具。

    基于原生JavaScript完成的网页端2048游戏,适配移动端,绑定键盘和鼠标滑动事件.zip

    在这个基于原生JavaScript实现的网页端2048游戏中,开发者充分利用了JavaScript的事件处理机制,使得游戏不仅可以在桌面浏览器上运行,同时也适配了移动端设备,为用户提供了一种跨平台的游戏体验。以下是对这个项目...

    kibo.rar_javascript

    总的来说,`kibo`库为JavaScript开发者提供了一个强大的工具,帮助他们更轻松地管理和响应键盘事件,从而增强Web应用的用户交互体验。如果你在项目中遇到需要处理大量键盘交互的情况,`kibo`库无疑是一个值得考虑的...

    Node.js-Node.js全局键盘和鼠标侦听器

    在描述中,我们看到“全局键盘和鼠标侦听器”,这意味着开发者可以编写代码来捕捉系统范围内的键盘事件(如按键按下、释放)和鼠标事件(如点击、移动、滚动)。这对于创建跨平台的用户交互程序非常有用,因为它们能...

    键盘控制图标移动

    例如,Java中的`KeyListener`接口,Python的`Tkinter`库中的`bind`方法,JavaScript的`addEventListener`函数可以监听键盘事件,如`keydown`和`keyup`。 2. 事件处理函数:当键盘事件发生时,我们需要定义一个事件...

    js实现虚拟键盘

    在这个场景中,我们讨论的是使用JavaScript来实现一个虚拟键盘,这对于触摸屏设备上的输入操作非常有用,比如在移动设备或平板电脑上,用户可能没有物理键盘,此时虚拟键盘就成为了必要的输入工具。 虚拟键盘的实现...

    Cloudgamer JavaScript Library v0.1 JavaScript 工具库发布.zip

    2. 输入管理:处理用户的键盘、鼠标和触摸输入,提供便捷的事件监听和响应机制。 3. 网络接口:可能包含WebSocket或其他协议的网络通信功能,支持实时多人在线游戏。 4. 时间和动画:提供时间管理和帧率控制,确保...

    JAVASCRIPT事件[借鉴].pdf

    此外,Dreamweaver等工具提供了图形化的事件管理界面,如行为面板,使得开发者可以更直观地添加和管理事件。例如,调用JavaScript函数、改变元素属性、检查浏览器或插件类型、控制多媒体播放、拖动层以及跳转链接等...

    javascript完全学习手册1 源码

    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 ...

    视奏训练工具_JavaScript_代码_下载

    2. **事件处理**:利用addEventListener等方法,JavaScript可以监听用户的键盘输入、鼠标点击等事件,实现对视奏练习的实时响应。 3. **AJAX通信**:如果工具需要从服务器获取乐谱或用户数据,JavaScript可以通过...

    javascript编写的小游戏

    例如,在"SkyPlane"游戏中,玩家可能通过键盘控制飞机移动,这就需要JavaScript监听键盘事件,并根据按键动作更新飞机的位置。 动画是游戏视觉效果的重要组成部分。在JavaScript中,可以使用requestAnimationFrame...

    js判断+ 键盘

    8. **项目构建**:`build.xml`和`project.xml`可能是指Apache Ant或Maven的构建文件,`ivy.xml`可能是Apache Ivy的依赖管理配置,这些都是Java项目常见的构建和依赖管理工具。这些工具可能会用到JavaScript编译或...

    JavaScript 第五章 JavaScript控制CSS

    这通常需要结合CSS的过渡效果(transition)和关键帧动画(keyframe animation)来完成,而JavaScript则负责触发这些动画和管理状态。 另一方面,"制作页面小广告-素材"可能指的是在网页上显示浮动广告或弹窗广告。...

    JavaScript脚本程序设计

    常见的事件有点击(click)、鼠标移动(mousemove)、键盘输入(keydown)等,通过addEventListener和removeEventListener方法添加和移除事件监听器。 4. **AJAX异步通信**:Asynchronous JavaScript and XML,虽然...

Global site tag (gtag.js) - Google Analytics