6.Event分析
prk/彭仁夔 08-08-26
对于javascript事件扩展,所有的lib都差不多。和jquery和prototype,yui和Ext,其要解决的首要问题是兼容性,所有lib都会对event进行包裹,统一其属性解决其兼容性。对于事件的操作无非是addEvent,fireEvent,removeEvent这三个事件方法。一般lib都会对浏览器的提供的函数做一些扩展,解决兼容性内存泄漏等问题。第三个问题就是如何得到domReady的状态。
6.1 event的包裹
浏览器的事件兼容性是一个令人头疼的问题。IE的event在是在全局的window下,而mozilla的event是事件源参数传入到回调函数中。还有很多的事件处理方式也一样。
Jquery提供了一个 event的包裹,这个相对于其它的lib提供的有点简单,但是足够使用。
//对事件进行包裹。
fix : function(event) {
if (event[expando] == true) return event;//表明事件已经包裹过
//保存原始event,同时clone一个。
var originalEvent = event; ①
event = { originalEvent : originalEvent};
for (var i = this.props.length, prop;i;) {
prop = this.props[--i];
event[prop] = originalEvent[prop];
}
event[expando] = true;
//加上preventDefault and stopPropagation,在clone不会运行
event.preventDefault = function() { ②
// 在原始事件上运行
if (originalEvent.preventDefault)
originalEvent.preventDefault();
originalEvent.returnValue = false;
};
event.stopPropagation = function() {
// 在原始事件上运行
if (originalEvent.stopPropagation)
originalEvent.stopPropagation();
originalEvent.cancelBubble = true;
};
// 修正 timeStamp
event.timeStamp = event.timeStamp || now();
// 修正target
if (!event.target) ③
event.target = event.srcElement || document;
if (event.target.nodeType == 3)//文本节点是父节点。
event.target = event.target.parentNode;
// relatedTarget
if (!event.relatedTarget && event.fromElement) ④
event.relatedTarget = event.fromElement == event.target
? event.toElement : event.fromElement;
// Calculate pageX/Y if missing and clientX/Y available
if (event.pageX == null && event.clientX != null) { ⑥
var doc = document.documentElement, body = document.body;
event.pageX = event.clientX
+ (doc && doc.scrollLeft || body && body.scrollLeft || 0)
- (doc.clientLeft || 0);
event.pageY = event.clientY
+ (doc && doc.scrollTop || body && body.scrollTop || 0)
- (doc.clientTop || 0);
}
// Add which for key events
if (!event.which && ((event.charCode || event.charCode === 0) ⑦
? event.charCode : event.keyCode))
event.which = event.charCode || event.keyCode;
// Add metaKey to non-Mac browsers
if (!event.metaKey && event.ctrlKey) ⑧
event.metaKey = event.ctrlKey;
// Add which for click: 1 == left; 2 == middle; 3 == right
// Note: button is not normalized, so don't use it
if (!event.which && event.button) ⑨
event.which = (event.button & 1 ? 1 : (event.button & 2
? 3 : (event.button & 4 ? 2 : 0)));
return event;
},
上面的代码①处保留原始事件的引用,同时clone原始事件。在这个clone的事件上进行包裹。②处在原始事件上运行preventDefault 和 stopPropagation两个方法达到是否阻止默认的事件动作发生和是否停止冒泡事件事件向上传递。
③处是修正target个,IE中采用srcElement,同时对于文本节点事件,应该把target传到其父节点。
④处relatedTarget只是对于mouseout、mouseover有用。在IE中分成了to和from两个Target变量,在mozilla中没有分开。为了保证兼容,采用relatedTarget统一起来。
⑥处是进行event的坐标位置。这个是相对于page。如果页面可以scroll,则要在其client上加上scroll。在IE中还应该减去默认的2px的body的边框。
⑦处是把键盘事件的按键统一到event.which的属性上。Ext中的实现ev.charCode || ev.keyCode || 0; ⑨则是把鼠标事件的按键统一把event.which上。charCode、ev.keyCode一个是字符的按键,一个不是字符的按键。⑨处采用&的方式来进行兼容性的处理。 Ext 通过下面三行解决兼容问题。
var btnMap = Ext.isIE ? {1:0,4:1,2:2} : (Ext.isSafari ? {1:0,2:1,3:2} : {0:0,1:1,2:2}); this.button = e.button ? btnMap[e.button] : (e.which ? e.which-1 : -1);
①②③④⑤⑥⑦⑧⑨⑩
分享到:
相关推荐
简单的模拟jQuery底层封装方法
jquery封装好的js文件,快速写入jquery简单方便
jquery.event.drag jquery拖动插件
NULL 博文链接:https://gaojiewyh.iteye.com/blog/518989
这个基于jQuery的弹窗组件拥有漂亮的外观,良好的兼容性和易用性。
Jquery学习 Jquery源代码 Jquery数据库操作 Jquery学习 Jquery源代码 Jquery数据库操作 绝对有用,技术含量
对常用jquery的ajax函数进行封装,便于调用,会有不同错误的错误提醒
jQuery封装插件原理教学 Demo 面向初级 高手勿喷~
强大的运用jqueryApi 封装了很多js的应用以及css选择器 让懂css的人很容易上手
仿照jquery封装一个自己的js库(一)
几个自己 整合了一下的 jquery 简单效果源代码,嗯,很简单的,请大家多多指教
用Jquery将常用的地图工具缩放工具与测量工具封装起来,方便使用,有需要的下载,百度网盘下载地址http://pan.baidu.com/s/1gdjAVyr
jQuery基础教程 (Learning jQuery) 完整源代码
Jquery学习 Jquery源代码 Jquery数据库操作 绝对有帮助,请下载,有技术含量的,没有你骂我
jQuery实战 源代码 JQuery实战 源代码 JQuery
JQuery.UI.Dialog的封装,方便开发时的使用,供大家一起共同分享学习。
jQuery Tab封装库,内含动画版选项卡及滑动门 本Javascript UI库是基于jQuery的扩展,完成jQuery Tab功能,已封装成库,使用非常方便,内含动画版的选项卡及滑动门,当前很流行的网页设计模式,风格越简洁,当然你...
纯JS图片预览PhotoSwipe使用demo及jquery插件封装,解压访问demo1,demo2页面,demo2页面使用jquery做成图片预览插件,直接调用$("").photoSwipe({}),就可实现图片预览效果
封装好了的验证码,不用自己在去添加控件,只用include页面进去就能达到效果,而且可以进行单击图片,和超链接进行刷新,分为字母和数字混合验证。