讀jQuery之六(緩存數據)

不少同窗在項目中都喜歡將數據存儲在HTMLElement屬性上,如javascript

1
2
3
4
<div data= "some data" >Test</div>
<script>
     div.getAttribute( 'data' );  // some data
</script>

給頁面中div添加了自定義屬性「data」及值「some data」。後續JS代碼中使用getAttribute獲取。java

 

jQuery從1.2.3開始提供了data/removeData方法用來存儲/刪除數據。1.6.1代碼片斷jquery

1
2
3
4
5
6
jQuery.extend({
     cache: {},
     // Please use with caution
     uuid: 0,
     ...
});

即給jQuery添加了靜態字段/方法,有jQuery.cache/jQuery.uuid/jQuery.expando等。下面分別介紹程序員


jQuery.cache 空對象,用來緩存。它的結構較複雜。緩存


jQuery.uuid 自增惟一的數字。app


jQuery.expando 字符串,使用Math.random生成,去掉了非數字字符。它做爲HTMLElement或JS對象的屬性名。dom

1
expando:  "jQuery"  + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g,  ""  ),


jQuery.noData JS對象,對於指定的HTMLElement禁用data方法。如embed、applet。ui


jQuery.hasData 用來判斷HTMLElement或JS對象是否具備數據。返回true或false。即若是調用了jQuery.data方法添加了屬性,則返回true。this

1
2
3
4
5
6
7
<div>aa</div>
<script>
     var  div = document.getElementsByTagName( 'div' )[0];
     $.hasData(div);  // false
     $.data(div,  'name' , 'jack' );
     $.hasData(div);  // true
</script>

 

jQuery.acceptData 用來判斷該元素是否能接受數據,返回true或false。在jQuery.data中使用。spa

 

jQuery.data 這是提供給客戶端程序員使用的方法,它同時是setter/getter。

  1. 傳一個參數,返回附加在指定元素的全部數據,即thisCachejQuery.data(el); // thisCache
  2. 傳二個參數,返回指定的屬性值jQuery.data(el, 'name'); 
  3. 傳三個參數,設置屬性及屬性值jQuery.data(el, 'name', 'jack');jQuery.data(el, 'uu', {});
  4. 傳四個參數,第四個參數pvt僅提供給jQuery庫自身使用。即jQuery._data方法中傳true。由於jQuery的事件模塊嚴重依賴於jQuery.data,爲避免人爲的不當心重寫在這個版本中加入的

 

jQuery.removeData 刪除數據。

上面是jQuery數據緩存模塊的總體概述,下面詳細說下jQuery.data方法。jQuery.data爲兩種對象提供緩存:JS對象和HTMLElement

1
2
3
4
5
6
7
8
9
10
11
12
// 爲JS對象提供緩存
var  myObj = {};
$.data(myObj,  'name' 'jack' );
$.data(myObj,  'name' );  // jack
 
// 爲HTMLElement提供緩存
<div id= "xx" ></div>
<script>
     var  el = document.getElementById( 'xx' );
     $.data(el,  'name' 'jack' );
     $.data(el,  'name' );  // jack
</script>

 

內部實現上也是有區別的,


1,爲JS對象提供緩存時,直接將數據保存在JS對象上。cache爲JS對象。此時會偷偷的給JS對象添加個屬性(相似於jQuery16101803968874529044),屬性值也是個JS對象。舉例說明

1
2
3
var  myObj = {};
$.data(myObj,  'name' 'jack' );
console.log(myObj);

 

myObj的結構以下

1
2
3
4
5
myObj = {
     jQuery16101803968874529044 : {
         name :  'jack'
     }
}

 

「jQuery16101803968874529044」這個字符串在data內部命名爲id(注意並不是HTMLElement元素的id),它實際就是jQuery.expando。上面已經提到它是在jQuery.js引入到頁面後隨機生成的。

 

2,爲HTMLElement提供緩存時,卻不會直接保存在HTMLElement上。而是保存在jQuery.cache上。cache爲jQuery.cache。此時先給HTMLElement添加屬性(相似於jQuery16101803968874529044),屬性值爲數字(1,2,3遞增)。即只將一些數字保存在了HTMLElement上,不會直接將數據置入。這是由於IE老版本中可能會存在內存泄露危險。而HTMLElement如何與jQuery.cache創建聯繫呢? 仍是id。剛剛提到屬性值數字就是id。舉例說明

1
2
3
4
5
6
7
<div id= "xx" ></div>
<script>
     var  el = document.getElementById( 'xx' );
     $.data(el,  'name' 'jack' );
     console.log(el[jQuery.expando]);  // 1
     console.log(jQuery.cache);  // {1 : {name:'jack'}}
</script>

  

el 上添加了屬性jQuery.expando,值爲id,這個id是從1開始遞增的。而id又做爲jQuery.cache的屬性(key)。這樣就HTMLElement就與jQuery.cache創建了聯繫。如圖





不知注意到沒有,jQuery.data還有第四個參數pvt,這個參數只在jQuery._data中使用。

1
2
3
4
// For internal use only.
_data:  function ( elem, name, data ) {
     return  jQuery.data( elem, name, data,  true  );
},

  

jQuery._data從命名上就指定它是私有的,使用jQuery的客戶端程序員不該該去調用該方法。jQuery的API文檔上也不會公開它。


jQuery的數據緩存模塊從1.2.3到1.6.1幾乎每一個版本都在變。jQuery._data的提出就是爲了不客戶端程序員覆蓋/重寫了默寫模塊。如jQuery事件模塊中事件handler等就使用jQuery.data存儲,若是重寫了該模塊。那麼事件模塊將癱瘓。所以特地添加了pvt參數及jQuery._data方法。


但若是你刻意要破壞,那麼仍是能夠作的。以下

1
2
3
4
5
6
7
8
9
10
<div id= "xx" >Test</div>
<script>
     $( '#xx' ).click( function (){
         alert( 'click' );
     });
     // 語句1
     $.data($( '#xx' )[0],  'events' '' true );
     // 語句2
     //$._data($('#xx')[0], 'events', '');
</script>

  

點擊div[id=xx]將不會觸發點擊事件。

 

整個jQuery.data設置(set)數據緩存的過程就是如此,理解的這個。取數據(get)的過程就好理解了。不重複。

最後,我會給zChian.js添加zChain.data/removeData方法,由於是「迷你版」,僅給HTMLElement添加數據緩存。請注意。

 

相關:

http://msdn.microsoft.com/en-us/library/Bb250448

http://bugs.jquery.com/ticket/6807

相關文章
相關標籤/搜索