标签可以将其 “editable” 属性设为 true,而这里采用的是给其设一个 tabindex 值。代码如下:
$ele.attr('tabindex', 1);
另外,焦点事件的触发需要点击元素或者 TAB 切换,而这并不符合人类的直觉,因此需要监听鼠标移入事件,使目标元素“自动”地获得焦点:
$ele.on('mouseenter', function(){
$ele.focus();
});
2. 监听键盘事件
由于项目面向的客户所使用的浏览器以chrome为主(实际上是36x浏览器),因此没有针对浏览器做任何适配,仅仅使用了 jQuery的事件监听:
$ele.on('keydown', this._keyDownHandler.bind(this));
由于实现是控件化的,所以定义了一个私有方法 _keyDownHandler 来响应键盘的动作。
3. 按键事件甄别
jQuery事件监听器返回的事件对象信息较多,因此需要进行甄别,为此定义了一个私有方法 _keyCodeProcess 来处理按键
function _keyCodeProcess(e){
var code = e.keyCode + '';
var altKey = e.altKey;
var ctrlKey = e.ctrlKey;
var shiftKey = e.shiftKey;
var threeKey = altKey && ctrlKey && shiftKey;
var ctrlAlt = altKey && ctrlKey;
var altShift = altKey && shiftKey;
var ctrlShift = shiftKey && ctrlKey;
var keyTypeSet = this.keyTypeSet;
var resStr = '';
if(threeKey){
resStr = keyTypeSet.threeKey[code];
} else if(ctrlAlt) {
resStr = keyTypeSet.ctrlAlt[code];
} else if(ctrlShift) {
resStr = keyTypeSet.ctrlShift[code];
} else if(altShift) {
resStr = keyTypeSet.altShift[code];
} else if(altKey) {
resStr = keyTypeSet.altKey[code];
} else if(ctrlKey) {
resStr = keyTypeSet.ctrlKey[code];
} else if(shiftKey) {
resStr = keyTypeSet.shiftKey[code];
} else {
resStr = keyTypeSet.singleKey[code];
}
return resStr
};
这里的 keyTypeSet 是一个类似于查找表的对象,里面存储了 ctrl、shift、alt按钮的各种类型组合,每种组合下又分别按照按键码存储一个自定义事件类型字符串,事件发生之后会从这里返回这个字符串,当然,没有对应自定义事件的时候,就老老实实地返回空字符串。
4. 事件分发
_keyCodeProcess 方法从事件中提取出了事件类型,我们提前将监听的回调函数存储在一个查找表 callback 中,并且“巧妙”地使得其键名刚好为自定义事件字符串前面加个“on”前缀,就可以方便地调用了,前述 _keyDownHandler 正是为此而设计的:
function _keyDownHandler(e){
var strCommand = this._keyCodeProcess(e);
var objEvent = {
type: '',
originEvent: e.originEvent
};
strCommand && this.callback['on' + strCommand](objEvent);
return null;
};
5. 事件订阅与解除订阅
前面说了,我们是把回调函数存储起来适时调用的,因此需要对外暴露一个“订阅”接口,让开发者可以方便地把自己的回调函数存储到对象实例中去,为此,我定义了一个 .bind接口:
function bind(type, callback, description){
var allType = this.allEventType;
if(allType.indexOf(type) === -1){
throwError('不支持改事件类型,请先扩展该类型,或采用其他事件类型');
}
if(!(callback instanceof Function)){
throwError('绑定的事件处理回调必须是函数类型');
}
this.callback['on' + type] = callback;
this.eventDiscibeSet[type] = description || '没有该事件的描述';
return this;
};
由于是给人用的,所以顺带做了下类型检查。
根据接口的“对称性”,有订阅最好也有解除订阅,因此定义了 .unbind接口,只有一句代码,实现如下:
function unbind(type){
this.callback['on' + type] = this._emptyEventHandler;
return this;
};
6.扩展自定义事件类型
键盘事件的组合丰富多彩,如果全部内置在控件中的话,会是很臃肿的,因此除了少数几个常见的组合键之外,开发者可以通过 .extendEventType 方法,来自定义组合键和返回的字符串:
function extendEventType(config){
var len = 0;
if(config instanceof Array){
len = config.length;
while(len--){
this._setKeyComposition(config[len]);
}
} else {
this._setKeyComposition(config);
}
return this;
};
其中的 ._setKeyComposition
是一个私有方法,用来写入自定义键盘事件的方法:
_setKeyComposition(config){
var altKey = config.alt;
var ctrlKey = config.ctrl;
var shiftKey = config.shift;
var threeKey = altKey && ctrlKey && shiftKey;
var ctrlAlt = altKey && ctrlKey;
var altShift = altKey && shiftKey;
var ctrlShift = shiftKey && ctrlKey;
var code = config.code + '';
if(threeKey){
this.keyTypeSet.threeKey[code] = config.type;
} else if(ctrlAlt) {
this.keyTypeSet.ctrlAlt[code] = config.type;
} else if(ctrlShift) {
this.keyTypeSet.ctrlShift[code] = config.type;
} else if(altShift) {
this.keyTypeSet.altShift[code] = config.type;
} else if(altKey) {
this.keyTypeSet.altKey[code] = config.type;
} else if(ctrlKey) {
this.keyTypeSet.ctrlKey[code] = config.type;
} else if(shiftKey) {
this.keyTypeSet.shiftKey[code] = config.type;
} else {
this.keyTypeSet.singleKey[code] = config.type;
}
return null;
};
这样,一个键盘事件监听控件就大功告成了,下面是完整实现代码:
/**
* @constructor 键盘事件监听器
* */
function KeyboardListener(param){
this._init(param);
}
!function(){
/**
* @private {String} param.ele 事件对象选择器
* */
KeyboardListener.prototype._init = function _init(param){
this.$ele = $(param.ele);
this._initEvents();
this._initEventType();
return null;
};
/**
* @private _emptyEventHandler 空白事件响应
* */
KeyboardListener.prototype._emptyEventHandler = function _emptyEventHandler(){
return null;
};
/**
* @private _initEventType 初始化所有初始自定义事件类型
* */
KeyboardListener.prototype._initEventType = function _initEventType(){
var allType = ['up', 'down', 'left', 'right', 'undo', 'redo', 'zoomIn', 'zoomOut', 'delete'];
var intLen = allType.length;
this.allEventType = allType;
this.callback = {};
this.eventDiscibeSet = {};
for(var intCnt = 0; intCnt
总结
以上所述是小编给大家介绍的基于 jQuery 实现键盘事件监听控件,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!