不少同窗在项目中都喜欢将数据存储在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。
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添加数据缓存。请注意。
相关: