问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

jquery中键盘事件小结

发布网友 发布时间:2022-04-23 09:38

我来回答

2个回答

懂视网 时间:2022-05-14 15:49

本篇文章给大家带来的内容是关于基于 jQuery的键盘事件监听控件的介绍(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

最近项目里要做一个画板,需要对键盘事件进行监听,来进行诸如撤回、重做、移动、缩放等操作,因此顺手实现了一个键盘事件监听控件,期间略有收获,整理出来,希望对大家有所帮助,更希望能获得高手的指点。

1. 自动获取焦点

似乎浏览器的键盘事件只能被那些可以获得焦点的元素设置监听,而通常需要监听事件的 <p>、<CANVAS> 元素都不能获得焦点,因此需要修改目标元素的某些属性使其可以获得焦点,另外一种可行的方法是将事件委托给诸如 <INPUT> 标签。这里采用的是第一类方法,当然,可以修改的属性也不止一种,例如,对于 <p> 标签可以将其 “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 < intLen; intCnt++){
  this.callback['on' + allType[intCnt]] = KeyboardListener.prototype._emptyEventHandler;
 }

 return null;
 };

 /**
 * @private _initEvents 绑定 DOM 事件
 * */
 KeyboardListener.prototype._initEvents = function _initEvents(){
 var $ele = this.$ele;

 $ele.attr('tabindex', 1);

 $ele.on('mouseenter', function(){
  $ele.focus();
 });

 $ele.on('keydown', this._keyDownHandler.bind(this));

 this.keyTypeSet = {
  altKey: {},
  ctrlAlt: {},
  ctrlKey: {},
  threeKey: {},
  altShift: {},
  shiftKey: {},
  ctrlShift: {},
  singleKey: {}
 };

 // 支持一些内建的键盘事件类型
 this.extendEventType([
  {
  type: 'redo',
  ctrl: true,
  shift: true,
  code: 90
  },
  {
  type: 'undo',
  ctrl: true,
  code: 90
  },
  {
  type: 'copy',
  ctrl: true,
  code: 67
  },
  {
  type: 'paste',
  ctrl: true,
  code: 86
  },
  {
  type: 'delete',
  code: 46
  },
  {
  type: 'right',
  code: 39
  },
  {
  type: 'down',
  code: 40
  },
  {
  type: 'left',
  code: 37
  },
  {
  type: 'up',
  code: 38
  }
 ]);

 return null;
 };

 /**
 * @private _keyDownHandler 自定义键盘事件分发
 * */
 KeyboardListener.prototype._keyDownHandler = function _keyDownHandler(e){
 var strCommand = this._keyCodeProcess(e);

 var objEvent = {
  type: '',
  originEvent: e.originEvent
 };

 strCommand && this.callback['on' + strCommand](objEvent);

 return null;
 };

 /**
 * @private _keyCodeProcess 处理按键码
 * */
 KeyboardListener.prototype._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
 };


 /**
 * @private _setKeyComposition 自定义键盘事件
 * @param {Object} config 键盘事件配置方案
 * @param {String} config.type 自定义事件类型
 * @param {keyCode} config.code 按键的码值
 * @param {Boolean} [config.ctrl] 是否与 Ctrl 形成组合键
 * @param {Boolean} [config.alt] 是否与 Alt 形成组合键
 * @param {Boolean} [config.shift] 是否与 Shift 形成组合键
 * */
 KeyboardListener.prototype._setKeyComposition = function _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;
 };

 /**
 * @method extendEventType 扩展键盘事件类型
 * @param {Object|Array<object>} config 键盘事件配置方案
 * @param {String} config.type 自定义事件类型
 * @param {keyCode} config.code 按键的码值
 * @param {Boolean} [config.ctrl] 是否与 Ctrl 形成组合键
 * @param {Boolean} [config.alt] 是否与 Alt 形成组合键
 * @param {Boolean} [config.shift] 是否与 Shift 形成组合键
 * */
 KeyboardListener.prototype.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;
 };

 /**
 * @method bind 绑定自定义的键盘事件
 * @param {String} type 事件类型 如:['up', 'down', 'left', 'right', 'undo', 'redo', 'delete', zoomIn, 'zoomOut']
 * @param {Function} callback 回调函数,参数为一个自定义的仿事件对象
 * @param {String} description 对绑定事件的用途进行说明
 * */
 KeyboardListener.prototype.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;
 };
 /**
 * @method unbind 解除事件绑定
 * @param {String} type 事件类型
 * */
 KeyboardListener.prototype.unbind = function unbind(type){
 this.callback['on' + type] = this._emptyEventHandler;

 return this;
 };
}();

【相关推荐:jQuery视频教程】

热心网友 时间:2022-05-14 12:57

一、首先需要知道的是:
1、keydown()
keydown事件会在键盘按下时触发.
2、keyup()
keyup事件会在按键释放时触发,也就是你按下键盘起来后的事件
3、keypress()
keypress事件会在敲击按键时触发,我们可以理解为按下并抬起同一个按键
二、获得键盘上对应的ascII码:
$(document).keydown(function(event){
alert(event.keyCode);
});
$tips:
上面例子中,event.keyCode就可以帮助我们获取到我们按下了键盘上的什么按键,他返回的是ascII码,比如说上下左右键,分别是38,40,37,39;
三、实例(当按下键盘上的左右方面键时)
代码如下:
$(document).keydown(function(event){
//判断当event.keyCode
为37时(即左方面键),执行函数to_left();
//判断当event.keyCode
为39时(即右方面键),执行函数to_right();
if(event.keyCode
==
37){
to_left();
}else
if
(event.keyCode
==
39){
to_right();
}
else
if
(event.keyCode
==
38){
to_top();
}
else
if
(event.keyCode
==
40){
to_bottom();
}
});
function
to_left(){
$(".abc").css({'left':'-=10'});}
function
to_right(){
$(".abc").css({'left':'+=10'});}
function
to_top(){$(".abc").css({'top':'-=10'});}
function
to_bottom(){$(".abc").css({'top':'+=10'});}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
人类如何才能悬浮在空中? - 知乎 人体悬浮术是真的存在吗 人体怎样才能真正的在空中悬浮 小孩c蛋白反应高是什么原因 (2014?南海区二模)如图所示,物重G为2000N,小红用800N的拉力花2s的时间... 苹果13系列升级iOS15.5好吗? 出生2o12年11月20日2点姓石光字辈取名 求龙凤胎名字:2012年6月21日(农历5月初3)凌晨0点40分出生,大的为龙,小... by和take有什么区别 takeby后面跟交通工具的区别 五常大米是最好吃的大米吗?那吉林大米比谁更好吃? QQ三国边境之战怎么玩 糙米好吗?哪家糙米最好? qq三国商城里的置身事外丸时效 如何挑选五常大米? qq三国置身事外卷怎么得到? 华为手机怎么拍拍对方 QQ三国置身事外丸怎么做? 糙米是什么米?是那里生产的? QQ三国 置身事外丸的一个问题 伊尹祠的柏树 QQ三国置身事外丸用了能使用多长时间? qq三国的置身事外书多小钱的? 糙米哪里产的比较好? 怎样用微信拍拍对方 QQ三国中的制符师多少级可以做召唤单?置身事外? 五常大米为什么好吃 怎么在微信里拍拍对方 QQ三国的置身 苏宁易购买苹果手机靠谱吗,没事吧? jquery方面的技术材料等。 糙米是大米吗?东北大米有好多!如何选择呢? 为什么我的电脑主板只有24针接口 jQuery键盘事件中event.keyCode==13相当于按下了那个键 js jquery 键盘事件 jquery 键盘默认事件问题 重要桥梁拆除的时候我们需要哪些手续? 我要“桥梁工程施工合同范本”, 桥梁合同书怎么写, 公路桥梁工程承包合同范本是什么 桥梁拆除施工资质 桥梁施工合同 代理商防止厂家过河拆桥合同条款与法律依据 桥梁承包合同需要注意哪些套路 2018年桥梁劳务合同范本 求桥梁施工合同协议书 公路桥梁工程承包合同范本有法律效力吗 桥梁拆除费用多少啊?有人可以告诉我吗? 河道桥梁拆除施工方案 桥梁拆除需要上报交通厅吗