很久以前,我還在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的注冊的事件逐一執行就可以了。這其實是一種通用的事件處理機制,事件處理機制是一種典型的觀察者設計模式。