前言:
周六看了司徒的一篇文章,觉得这个topic不错,觉得效仿一下,深入剖析一下jQuery的data相关的实现。主要还是对页面的某些元素进行数据绑定及存储相关的操作,本topic是以一个专题的形式呈现,因为会比较多个版本之间的差异和优化。
正文:
还是老规矩吧,我喜欢在研究之前先问几个问题:
- 哪些节点(或者说是标签)不能存储数据?
- 如何设计这个对应关系,一个元素多份数据的时候,多份数据多个节点的时候?
- 如果节点是window呢,数据存储有区别吗?
- jQuery每一个版本的实现是否有差异?
- 参数的优化,比如对应一个key,存多个value或者一个对象等
- 。。。。。。。。
呵呵,好像还挺多问题的,慢慢地我一个一个解答。
确切地讲,从 jquery-1.2就开始有data相关的api实现!
//1.2版本的expando是前缀jQuery+时间戳
var expando = "jQuery" + (new Date()).getTime(),
uuid = 0, //uuid从0开始
win = {}; //window绑数据都是扔到这边
//扩展jquery的api实现方式
jQuery.extend({
cache:{}, //数据存储的集合
/*
@name data
@param elem 绑定存储数据的节点对象
@param name 数据的key
@param data 数据
@info 元素和数据之间挂接的关联关系:元素有一个属性expando对应id
id是uuid自加的结果
*/
data:function(elem,name,data){
//判断节点是否是window
elem = elem== window ? win : elem;
var id = elem[expando];
if(!id){
//新绑定的uuid自加
id = elem[expando] = ++ uuid;
}
//如果有name而且没有被cache注册数据过
if(name && !jQuery.cache[id]){
//cache是按照id来对应数据的
jQuery.cache[id][name] = data;
}
return name ? jQuery.cache[id][name] : id;
},
/*
@name removeData
@param elem 绑定存储数据的节点对象
@param name 数据的key
*/
removeData:function(elem,name){
//判断节点是否是window
elem = elem == window ? win : elem;
var id = elem[expando];
//删除特定name的数据
if(name){
if(jQuery.cache[id]){
delete jQuery.cache[id][name];
name = "";
for(name in jQuery.cache[id]) break;
if(!name){
jQuery.removeData(elem);
}
}
}else{
//删除elem的绑定的所有数据
try{
delete elem[expando];
}catch(e){
if(elem.removeAttribute){
elem.removeAttribute(expando);
}
}
delete jQuery.cache[id];
}
}
});
很多人关注:咋使用?
<div id="out1"></div>
var elem = document.getElementById("out1");
//设置
$.data(elem,'name','zhangyaochun');
console.log($.data(elem,'name'));
//删除
$.removeData(elem);
console.log($.data(elem,'name'));
结果一次输出zhangyaochun,一次输出undefined
我们再看一下对应关系:
先看看$.cache咋存的?
再看看elem里面咋对应的?
为了不让各位视觉疲劳,下篇来讲哪个版本开始那些标签不能存储数据!!
@ 理想国际大厦 -------------- 地方换了,晚走的习惯还是没有变。。。。。。。。。。