很多同學在項目中都喜歡將數據存儲在HTMLElement屬性上,如
1
2
3
4
|
<div data=
"some data"
>Test</div>
<script>
div.getAttribute(
'data'
);
// some data
</script>
|
給頁面中div添加了自定義屬性“data”及值“some data”。后續JS代碼中使用getAttribute獲取。
jQuery從1.2.3開始提供了data/removeData方法用來存儲/刪除數據。1.6.1代碼片段
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 自增唯一的數字。
jQuery.expando 字符串,使用Math.random生成,去掉了非數字字符。它作為HTMLElement或JS對象的屬性名。
1
|
expando:
"jQuery"
+ ( jQuery.fn.jquery + Math.random() ).replace( /\D/g,
""
),
|
jQuery.noData JS對象,對於指定的HTMLElement禁用data方法。如embed、applet。
jQuery.hasData 用來判斷HTMLElement或JS對象是否具有數據。返回true或false。即如果調用了jQuery.data方法添加了屬性,則返回true。
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中使用。
jQuery.data 這是提供給客戶端程序員使用的方法,它同時是setter/getter。
- 傳一個參數,返回附加在指定元素的所有數據,即thisCachejQuery.data(el); // thisCache
- 傳二個參數,返回指定的屬性值jQuery.data(el, 'name');
- 傳三個參數,設置屬性及屬性值jQuery.data(el, 'name', 'jack');jQuery.data(el, 'uu', {});
- 傳四個參數,第四個參數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添加數據緩存。請注意。