javascript快捷键实现

       在互联网上关于javascript快捷键实现的方式寥寥无几,而且不能满足当前项目要求,应项目组要求关于网页快捷键提供一个相对通用的解决方案,因此产生此篇文章。

一、项目需求:

      1、使用键盘上的左、右键在各个控件之间进行焦点转移。左键向上转移焦点(类似与shift+tab键);右键向下转移焦点(类似与tab键)。

       2、使用键盘上下键在列表中上下转移焦点。

       3、能够使用enter、esc键进行form表单数据保存、取消。

二、总体思路:

      html各控件本身都提供了tab-index属性,设置该属性后通过tab键就可以实现焦点在各控件间按照tab-index值,由小到大进行焦点转移。

1、在网页进行装载(调用body的onload事件)时候将所有具有tab-index的控件放入Array数组中,按照tab-index值排序。

2、在按左、右键的时,定位当前控件,然后在定位Array中的前一个或后一个控件,然后让该控件获得焦点。

3、关于上、下键进行表单跳转,强制要求元素必须在html的table表格中,通过表格的上下td进行焦点转移,具体实现可以参见实现代码。

三、实现代码:

     实现由一个js文件和一个html测试页面组成。

1、hotkey.js文件,该文件以prototype方式定义HotKey类,该类包括快捷键定义、上下左右转移方法实现、快捷键注册方法。具体内容如下所示:

var __KEY_ADDNEW	= 65;
var __KEY_SAVE	= 13;
var __KEY_ESC 	= 27;
var __KEY_LEFT	= 37;
var __KEY_RIGHT	= 39;
var __KEY_UP	= 38;
var __KEY_DOWN	= 40;
function HotKey(){
	this.keyArray = new Array();
	this.tabArray = new Array();
	//this._self = this;
	var _self = this;
	var _arr = new Array();
	_arr.push(this);
	this.registerKey(__KEY_LEFT,this.movetoprevious,_arr);
	this.registerKey(__KEY_RIGHT,this.movetonext,_arr);
	this.registerKey(__KEY_DOWN,this.movetodown);
	this.registerKey(__KEY_UP,this.movetoup);
}

HotKey.prototype.loadTabElements = function(){	
	var _ele = document.getElementsByTagName("input");
	for(var i=0;i<_ele.length;i++){
		if(null!=_ele[i].getAttribute("tabIndex")){
			this.tabArray.push({"tabIndex":_ele[i].getAttribute("tabIndex"),"element":_ele[i]});
		}
	}
	this.tabArray.sort(function compare(a,b){
							return Number(a.tabIndex)-Number(b.tabIndex);
						}
					);

	
}
HotKey.prototype.getTabArray=function(){
	return this.tabArray;
}
//转移到下一个焦点(tab)
HotKey.prototype.movetonext=function(p_hotkey){
	var _array = p_hotkey.getTabArray();
	if(event.srcElement==_array[_array.length-1].element){
		_array[0].element.focus();				
		_array[0].element.select();
		return;
	}
	for(var i=0;i<_array.length;i++){
		if(event.srcElement==_array[i].element){
			if(null!=_array[i+1]){
				_array[i+1].element.focus();				
				_array[i+1].element.select();
			}
		}
	}	
}
//转移到上一个焦点(shift+tab)
HotKey.prototype.movetoprevious=function(p_hotkey){
	var _array = p_hotkey.getTabArray();
	if(event.srcElement==_array[0].element){
		_array[_array.length-1].element.focus();				
		_array[_array.length-1].element.select();	
		return;
	}
	for(var i=_array.length-1;i>-1;i--){
		if(event.srcElement==_array[i].element){
			if(null!=_array[i-1]){
				_array[i-1].element.focus();				
				_array[i-1].element.select();
			}
		}
	}	
}
HotKey.prototype.movetodown=function(){
	var _td = event.srcElement.parentNode;
	var _tr = _td.parentNode;
	var _tbl = _tr.parentNode.parentNode;
	if(null==_tbl || "TABLE"!=_tbl.tagName) return;
	var k = 0;
	for(var i=0;i<_tr.cells.length;i++){
		if(_td==_tr.cells[i]) {
			k=i;
			break;
		}
	}
	var _nexttr = _tr.nextSibling;
	if(null==_nexttr) return;
	_nexttr.cells[k].childNodes[0].focus();
	_nexttr.cells[k].childNodes[0].select();
}
HotKey.prototype.movetoup=function(){
	var _td = event.srcElement.parentNode;
	var _tr = _td.parentNode;
	var _tbl = _tr.parentNode.parentNode;
	if(null==_tbl || "TABLE"!=_tbl.tagName) return;
	var k = 0;
	for(var i=0;i<_tr.cells.length;i++){
		if(_td==_tr.cells[i]) {
			k=i;
			break;
		}
	}
	var _previousttr = _tr.previousSibling;
	if(null==_previousttr) return;
	_previousttr.cells[k].childNodes[0].focus();
	_previousttr.cells[k].childNodes[0].select();
}

HotKey.prototype.registerKey=function(p_key,p_callback,p_args){
	//判断是否重复注册,新的替换旧的;
	var isexist = false;
	for(var i=0;i<this.keyArray.length;i++){
		if(p_key==this.keyArray[i].key){
			this.keyArray[i]={"key":p_key,"_callback":p_callback,"_args":p_args};
			isexist=true;

		}
	}
	if(!isexist){
		this.keyArray.push({"key":p_key,"_callback":p_callback,"_args":p_args});
	}
	var _self = this;
	document.οnkeydοwn=function(){
		for(var i=0;i<_self.keyArray.length;i++){				
			if(event.keyCode==_self.keyArray[i].key){ 
				if(null==_self.keyArray[i]._args || _self.keyArray[i]._args=="undefined"){
					var _array = new Array();
					_array.push(event);
					_self.keyArray[i]._callback.apply(this,_array);
				}else{
					_self.keyArray[i]._args.push(event);
					_self.keyArray[i]._callback.apply(this,_self.keyArray[i]._args);
				}
				event.returnValue=false;
				break;

			}
		}			
	}
}

  2、hotkey.htm文件,用来演示快捷键实现的参考样例。代码如下所示:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=gbk" />
<meta http-equiv="content-language" content="zh-CN" />
<title> new document </title>
<script language=JScript.Encode src="hotkey.js"></script>	
 
<style type="text/css"> 
*:focus {
	border:1px dotted blue;
}
</style>
</head>
 
<body οnlοad="hotkey.loadTabElements();">
<input type="text" name="oo" tabIndex="1" value="1">
<table id="tt" border="1">
	<tr>
		<td>1</td>
		<td><input id="yy" type="checkbox" tabIndex="2"><input id="yyy" type="hidden"></td>
		<td id="11"><input name="kk[0]" value="0000" tabIndex="3"></td>
		<td>&nbsp;</td><td><input name="jj[0]" value="00001111" tabIndex="4"></td>
		<td>&nbsp;</td>
	</tr>
	<tr>
		<td>2</td><td><input type="checkbox" tabIndex="5"><input id="yyy" type="hidden"></td>	<td><input name="kk[1]" tabIndex="6"></td><td>&nbsp;</td><td><input name="jj[1]" tabIndex="7"> </td><td>&nbsp;</td>
	</tr>
</table>
<input type="text" name="yy" tabIndex="8">
<input type="text" name="tt" tabIndex="9">
<br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<script language="JavaScript"> 
<!--
 
var hotkey = new HotKey();
var arr = new Array();
arr.push("save is ok");
hotkey.registerKey(__KEY_SAVE,toSave,arr);
hotkey.registerKey(__KEY_ESC,toEsc,null);
//hotkey.registerKey(__KEY_UP,toup,null);
 
function toup(){
	alert("toup");
}
function toSave(v){	
	alert(v);
}
function toEsc(){	
	alert("esc");
}
 
//-->
</script>
</body>
</html>

 说明:

  1、在页面设计时指定进行焦点停留控件的tab-index属性值。

  2、在页面加载时,必须指定body的οnlοad=hotkey.loadTabElements()。

  3、可以使用registerKey方法对程序中已经注册的键盘事件进行复写。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值