`
goodscript
  • 浏览: 71946 次
  • 性别: 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完全学习手册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 源码

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

    JavaScript权威指南(第6版)

    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 修改文档...

    JavaScript权威指南(第6版)(中文版)

    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 修改文档...

    JavaScript权威指南(第6版)中文文字版

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

    JavaScript权威指南(第6版)

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

    JavaScript权威指南(第六版) 清晰-完整

    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 修改文档...

    JavaScript权威指南(第6版) 中文版

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

    JavaScript实战

    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 教程:添加...

    JSUI:用于管理JavaScript应用程序的功能强大的UI工具包

    开发人员和设计师的浏览器 :school: Academy-交互式React和GraphQL研讨会 :love_letter: 用于Twitter DM和Twitter的独立应用程序UI :hammer_and_wrench: 用于可视化组织,创建和管理JavaScript项目的工具。...

    phoenix:轻量级的macOSOS X窗口和可通过JavaScript编写脚本的应用程序管理器

    如果您喜欢用JavaScript编写自己的窗口或应用程序管理工具包的想法,Phoenix可能会为您提供所需的东西。 使用Phoenix,您可以绑定键盘快捷键和系统事件,并使用它们与macOS进行交互。 当前版本:2.6.6( ) 要求:...

    vs实现js格式化和代码折叠

    打开 菜单 --&gt; 工具 --&gt; 宏(Macro) --&gt; 宏资源管理器(Macro Explorer) ,在Explorer中选择新建的工程,修改Module名(右键),在Module名上双击,在打开的Macro IDE中进行编辑。 3. 在Module下,添加要实现的...

    脚本语言编程脚本语言编程

    1、(1)从控制面板-管理工具里打开IIS,将主目录设置为自己建的文件夹; (2)启动DW,新建站点,选择ASP服务器技术; (3)在DW的代码视图下编写脚本程序; (4)使用预览功能运行脚本程序。 2、提示: (1)使用...

    精通JS脚本之ExtJS框架.part2.rar

    本书共分17章,分别介绍了JavaScript的对象编程、JavaScript浏览器对象模型和事件机制、ExtJS的核心类库和组件、ExtJS的事件处理方式、设计进度条、设计工具栏和菜单栏、设计面板、设计表格、设计表单、设计数据表、...

    精通JS脚本之ExtJS框架.part1.rar

    本书共分17章,分别介绍了JavaScript的对象编程、JavaScript浏览器对象模型和事件机制、ExtJS的核心类库和组件、ExtJS的事件处理方式、设计进度条、设计工具栏和菜单栏、设计面板、设计表格、设计表单、设计数据表、...

    Dash_6.1.0_[TNT]_.zip

    Dash for mac是使用与Mac OS平台的软件编程文档管理工具,可以浏览API文档,以及管理代码片段工具。Dash自带了丰富的API文档,涉及各种主流的编程语言和框架。 可以浏览API文档,以及管理代码片段工具。Dash自带了...

    accdc:Standalone AccDC API是使用JavaScript构建的可伸缩,跨浏览器和跨平台兼容的动态内容管理系统,可自动呈现动态内容,以确保仅屏幕阅读器和键盘用户可以访问

    AccDC是可伸缩,跨浏览器和跨平台兼容的动态内容管理系统,可自动呈现动态内容,以确保仅屏幕阅读器和键盘用户的可访问性。 在皇家艺术协会的支持下,AccDC获得了美国劳工部的“无障碍获取奖”,并在2012年由美国...

Global site tag (gtag.js) - Google Analytics