1 js中的对象都是object,使用firebug查看都是Object:{}形式,js中的function默认返回的是this对象,任何代码只要知道this对象那么就比较容易的理解,jquery中绝大多数的this对象都是一个数组对象,可以广泛的支持设计的需要。
2 createDocumentFragment主要可以提高效率。可以配合缓存使用,这个主要是通过jquery对象的fragement属性来实现。
3 动态方法apply和call的广泛的使用和isFunction,isObject等方法的使用。
4 初始化中的new jQuery.fn.init中的 jQuery.fn为jQuery的prototype,方便闭包的实现和可扩展性,而且jQuery.fn.init.prototype=jQuery.fn,所以 jQuery.fn=== jQuery.prototype===jQuery.fn.init.prototype。
5 正则表达式的使用,靠,看了好久终于看懂了一些,比较的强大,对一些基本的操作进行了比较完美的分类。反正我是想不到啦。
6 var getData = function(elem, key){
return1 && 2 || null; //如果缓存里没有, 返回null
}
这里有点linux的味道,如果1和2都是true则返回2的结果,否则返回null
6 大量使用闭包,即匿名function,可以有效的减少js的冲突,增加可用性。
平时我们都是调用 click(func) 之类的函数, 而其实这些都是工具函数,真正和事件挂钩的函数是
jQuery.fn.bind - 调用 jQuery.event.add
jQuery.fn.unbind - 调用 jQuery.event.remove
jQuery.fn.trigger - 调用 jQuery.event.trigger
jQuery.fn.one - 调用 jQuery.fn.bind,Query.fn.unbind
要想知道jQuery的事件原理,必须读 jQuery.event.add
add:
function
( elem, types, handler, data ) {
//
只对节点操作。
if
( elem.nodeType
===
3
||
elem.nodeType
===
8
) {
return
;
}
//
IE 无法传递 window,而是复制这个对象 。
if
( jQuery.isWindow( elem )
&&
( elem
!==
window
&&
!
elem.frameElement ) ) {
elem
=
window;
}
//
如果 handler === false, 也就是说就是阻止某事件,
//
这样只要 bind("evt", false); 就是阻止此事件。
if
( handler
===
false
) {
handler
=
returnFalse;
}
else
if
(
!
handler ) {
return
;
}
//
handleObjIn 是内部处理句柄, handleObj 是直接使用的处理句柄。
var
handleObjIn, handleObj;
if
( handler.handler ) {
handleObjIn
=
handler;
handler
=
handleObjIn.handler;
}
//
为函数生成唯一的 guid 。具体下面介绍。
if
(
!
handler.guid ) {
handler.guid
=
jQuery.guid
++
;
}
//
获取一个节点的数据。
var
elemData
=
jQuery.data( elem );
//
如果没有数据,则直接返回。
if
(
!
elemData ) {
return
;
}
//
避免和原生的js对象混淆。
var
eventKey
=
elem.nodeType
?
"
events
"
:
"
__events__
"
,
//
这里就是关键。
//
elemData 是存储数据的位置, 而 elemData[ eventKey ] 就是存储当前事件的对象。 elemData.handle 就是当前绑定的所有函数数组。
//
也就是说,当我们绑定一个函数时,会往 elemData.handle 放这个函数,然后事件触发时,会遍历 elemData.handle 中函数然后去执行。
//
肯能有人会问,为什么这么做,因为原生的DOM内部也有一个 函数数组,事件触发后会执行全部函数。答案还是 兼容。
//
标准浏览器使用 addEventListener
//
IE 使用 attachEvent
//
而这2者还是有差距的。因为 addEventListener 执行函数的顺序即添加函数的顺序,然而 attachEvent 执行函数的顺序和添加的顺序是相反的。
//
jQuery 使用自定义的 handler 数组,好处有:
//
因为最后仅绑定一次原生事件,事件触发后,手动执行 数组中的函数。这样保证兼容。
//
同时也可以知道到底绑定了什么函数,可以方便 trigger 函数的完成。
events
=
elemData[ eventKey ],
eventHandle
=
elemData.handle;
//
一些功能。。
if
(
typeof
events
===
"
function
"
) {
eventHandle
=
events.handle;
events
=
events.events;
}
else
if
(
!
events ) {
if
(
!
elem.nodeType ) {
elemData[ eventKey ]
=
elemData
=
function
(){};
}
elemData.events
=
events
=
{};
}
//
如果是第一次执行,需创建 eventHandle
if
(
!
eventHandle ) {
//
eventHandle 就是真正绑定到原生事件的那个函数,这个函数用来执行events.hadlers 用。
elemData.handle
=
eventHandle
=
function
() {
//
Handle the second event of a trigger and when
//
an event is called after a page has unloaded
return
typeof
jQuery
!==
"
undefined
"
&&
!
jQuery.event.triggered
?
jQuery.event.handle.apply( eventHandle.elem, arguments ) :
undefined;
};
}
//
绑定函数和原生,这样可以保证函数可执行为目前作用域。
eventHandle.elem
=
elem;
//
处理 jQuery(...).bind("mouseover mouseout", fn);
types
=
types.split(
"
"
);
var
type, i
=
0
, namespaces;
while
( (type
=
types[ i
++
]) ) {
handleObj
=
handleObjIn
?
jQuery.extend({}, handleObjIn) :
{ handler: handler, data: data };
//
略
//
绑定 type guid
handleObj.type
=
type;
if
(
!
handleObj.guid ) {
handleObj.guid
=
handler.guid;
}
//
获取当前的函数数组。
var
handlers
=
events[ type ],
special
=
jQuery.event.special[ type ]
||
{};
//
如果第一次,则创建这个数组。
if
(
!
handlers ) {
handlers
=
events[ type ]
=
[];
//
特殊事件要执行 setup 而不是标准 addEventListener。
//
此行用来支持自定义的事件。
if
(
!
special.setup
||
special.setup.call( elem, data, namespaces, eventHandle )
===
false
) {
//
标准事件。 这里绑定的为 eventHandle
if
( elem.addEventListener ) {
elem.addEventListener( type, eventHandle,
false
);
}
else
if
( elem.attachEvent ) {
elem.attachEvent(
"
on
"
+
type, eventHandle );
}
}
}
//
自定义事件,执行 add
if
( special.add ) {
special.add.call( elem, handleObj );
if
(
!
handleObj.handler.guid ) {
handleObj.handler.guid
=
handler.guid;
}
}
//
不管是不是首次,都放入目前绑定的函数。
handlers.push( handleObj );
//
为实现 trigger 。
jQuery.event.global[ type ]
=
true
;
}
//
让IE下可以正常回收 elem 内存。
elem
=
null
;
},
8.2 事件对象
框架的义务当然也包括 事件参数的修复。jQuery 是自定义事件对象, 这个对象模拟真实事件对象。
根据上文可以知道,真正绑定事件的是一个函数,这个函数执行时会先 生成自定义事件对象, 然后把此对象作为参数调用所有的 handler 。
jQuery 自定义事件是 jQuery.Event 。 (代码 2583-2610 行)
jQuery.Event
=
function
( src ) {
//
支持 没有 new jQuery.Event
if
(
!
this
.preventDefault ) {
return
new
jQuery.Event( src );
}
//
略
}
分享到:
相关推荐
jQuery学习资料 锋利的Jquery 源码 锋利的Jquery 源码 锋利的Jquery 源码
昨天写了篇通过jQuery源码学习javascript(一),里面有一个定义对象C的方法,我早期也没有太注意这个方面的技术细节。后来我查了一下资料,发现里面有很多巧的地方。今天与大家分享
包括JQuery学习三季,里面包含从基础开始的JQuery源代码,可以直接在浏览器里运行使用
这是一份jquery的源码的解读,上面附有详细的解读和笔记,对于前端开发人员来说 这是一份不可多得的学习jquery框架的好资源
jQuery 源码 文档 插件 帮助您轻松学习jQuery
最近在做日志统计程序,发现对方的程序是在Jquery基础上进行开发的,而公司的网站的框架是prototype。而且我也早就想了解一下Jquery源码,故决定研究Jquery源码,模拟它的方法
jQuery 未压缩版本源码学习 本版本没有压缩。。。
本文主要以为学习参考书籍,为保证与书籍内容同步,以jQuery 1.7.2为学习版本进行。 本次学习主要使用“笨鸟多飞”的方式对相关例程代码进行逐行注释理解。 补充说明 多数情况下,内容不参考ES6新特性例如:块级作用...
<锋利的jquery>电子书的实验源码,用于自己的学习。jquery是js的超集,平时的开发过程中,原生的js用的倒没有jquery多
JQueryEasyUI学习笔记(十一)源码 右键菜单 冻结列
锋利的jquery源码,帮助大家学习jquery,更有利于页面的效果优化
官网下载的jQuery-master,1.12版本,相信对现代js技术有很深的理解和学习。
jquery学习资料jQuery DOM的操作jQuery插件源码jQuery插件等资料: jQuery DOM教辅.pdf jQuery DOM源码 jQuery DOM的操作.pdf jQuery 丰富的插件.pdf jQuery 事件的处理.pdf jQuery 元素选择器参考手册(教辅) .pdf ...
承接上两篇继续写下去。我尽量把我明白的地方给大家说清楚。有些大家的提问我也有点搞不明白,如果有人能解答,再好不过了
小弟整理,收藏的全是免积分的jQuery源码实例和学习资料地址
Jquery mobile 实例源码,适合初学者学习HTML5开发
jQuery源码含资源及PPT,非常有用的jQuery学习资料,总共分为三节
锋利的jQuery源码,不容错过,从第一章到最后一章都有,学习jQuery必备