很久以前,我还在cnblogs里面逛的时候就提出过一个问题(刚找了半天没找到)。不知道大家有没有发现,用jQuery选择器"选择"之后的DOM上会添加jQuery*********属性。
<
DIV
id
=d1
jQuery1294122065250
="1"
>
abc
</
DIV
>
首先jQuery1294122065250中的"1294122065250"其实是一个时间戳。看看jQuery的源代码。
var
expando
=
"
jQuery
"
+
now(), uuid
=
0
, windowData
=
{};
由于使用了闭包,这样每一个jQuery对象都有一个expando属性。
属性值jQuery1294122065250="1"的"1"其实是jQuery的缓存的key。
首先了解一下jQuery缓存的相关API:
- data(name):返回元素上储存的相应名字的数据
- data(name,value):在元素上存放数据,同时也返回value。
- jQuery.data(element,key,value):在元素上存放数据,返回jQuery对象。注意:这是一个底层方法。你应当使用.data()来代替。
- jQuery.data([element],[key]): 查询在元素上存放的数据。如果不指定参数,则会返回元素上面存放的所有数据,以Object的形式返回。注意:这是一个底层方法。你应当使用.data()来代替。
- removeData(data):移除元素上的缓存。
把jQuery.data方法是底层方法,data方法调用了该方法。要了解Query的缓存,最好的方法莫过于调试一下jQuery代码了。
<
script
type
="text/javascript"
>
$(
function
(){
var
$d1
=
$(
"
#d1
"
);
$d1.data(
"
key
"
,
"
value
"
);
var
v
=
$d1.data(
"
key
"
);
$d1.click(
function
(){
alert(
"
click
"
);
});
for
(
var
k
in
jQuery.cache){
alert(k
+
"
\n
"
+
jQuery.cache[k]);
}
debugger
;
});
</
script
>
<
div
id
="d1"
class
=""
>
abc
</
div
>
上面是一个简单的jQuery代码。在执行完$d1.data("key","value");后。经过调试后可以发现
jQuery是一个全局变量:
//
Define a local copy of jQuery
var
jQuery
=
function
( selector, context ) {
//
The jQuery object is actually just the init constructor 'enhanced'
return
new
jQuery.fn.init( selector, context );
},
//
Map over jQuery in case of overwrite
_jQuery
=
window.jQuery,
//
Map over the $ in case of overwrite
_$
=
window.$,
jQuery.data存放着所有的缓存key就是上面提到的DOM属性jQuery*********的值。
下面是读取缓存data函数的关键代码:
data:
function
( elem, name, data ) {
var
id
=
elem[ expando ], cache
=
jQuery.cache, thisCache;
thisCache
=
cache[ id ];
return
typeof
name
===
"
string
"
?
thisCache[ name ] : thisCache;
},
经过调试id 与jQuery********属性一致。直接通过jQuery.cache获取缓存值。
有缓存就必然会有清除缓存,不清除缓存意味着很有可能IE内存泄漏。
//
Prevent memory leaks in IE
//
Window isn't included so as not to unbind existing unload events
//
More info:
//
- http://isaacschlueter.com/2006/10/msie-memory-leaks/
if
( window.attachEvent
&&
!
window.addEventListener ) {
window.attachEvent(
"
onunload
"
,
function
() {
for
(
var
id
in
jQuery.cache ) {
if
( jQuery.cache[ id ].handle ) {
//
Try/Catch is to handle iframes being unloaded, see #4280
try
{
jQuery.event.remove( jQuery.cache[ id ].handle.elem );
}
catch
(e) {}
}
}
});
}
在window.unload时,jQuery将逐一删除jQuery.cache中的元素。
jQuery的事件绑定也利用了jQuery的缓存。上面的代码监听了#d1.click事件后,经过调试,可以发现,在缓存key为"events"上记录了监听的事件。
通过上面的调试,发现所谓的事件监听或者绑定bind,其实就是在缓存中注册一下处理函数,当事件触发时,将DOM的注册的事件逐一执行就可以了。这其实是一种通用的事件处理机制,事件处理机制是一种典型的观察者设计模式。