在互联网上关于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.onkeydown=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 onload="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> </td><td><input name="jj[0]" value="00001111" tabIndex="4"></td>
<td> </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> </td><td><input name="jj[1]" tabIndex="7"> </td><td> </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的onload=hotkey.loadTabElements()。
3、可以使用registerKey方法对程序中已经注册的键盘事件进行复写。
本文介绍了一种在网页中实现快捷键的通用方法,利用tab-index属性和键盘事件监听实现焦点转移,支持方向键和Enter/ESC键操作。
308

被折叠的 条评论
为什么被折叠?



