#jquery 源码分析-核心(4)数据缓存data和removeData
##data,removeData,常用方法
“`javascript
(element).data(key,data);//赋值
(element).data(key); //获取值
$(element).removeData(key) //移除值
例子:
html
<div id="test" ></div>
$("#test").data("test",12);
var data = $("#test").data("test") // 12
$("#test").removeData("test")
var data = $("#test").data("test") // undefined
##
(ele).data(k,y)和
.data(ele,k,value);之间关系,
(ele).data(k,y)是封装来的
.data(ele,k,value)
##$(ele).data(k,y)源码
“`javascript
jQuery.fn = jQuery.prototype = {
data: function( key, value ){
var parts = key.split(“.”);
parts[1] = parts[1] ? “.” + parts[1] : “”;
if ( value === undefined ) {
var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
if ( data === undefined && this.length )
data = jQuery.data( this[0], key );
return data === undefined && parts[1] ?
this.data( parts[0] ) :
data;
} else
return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
jQuery.data( this, key, value );
});
}
}
javascript
## data方法源码
data: function( elem, name, data ) {
elem = elem == window ?
windowData :
elem;
var id = elem[ expando ]; //expando = "jQuery" + now(),给元素新增一个属性expando
// Compute a unique ID for the element
if ( !id )
id = elem[ expando ] = ++uuid; //uuid = 0 自增,uuid在jquery内部是一个全局变量,所以不会出现重复
// Only generate the data cache if we're
// trying to access or manipulate it
if ( name && !jQuery.cache[ id ] )
jQuery.cache[ id ] = {};
// Prevent overriding the named cache with undefined values
if ( data !== undefined )
jQuery.cache[ id ][ name ] = data;
// Return the named cache data, or the ID for the element
return name ?
jQuery.cache[ id ][ name ] :
id;
}
expando =”jQuery” + now()
$(element).data(key,data),直传入2个参数,它地层调用data: function( elem, name, data ),将$(element)作为参数传入,data的数据缓存是给element新增一个属性elem[ expando ],将数据存储以键值对的模式在jQuery的cache的这个属性上,然后element新增一个属性elem[ expando ]的值和cache对应的键值是一样的,这样elem[ expando ]和cache就联系起来了,然后为了处理一个elemens有多个name的情况,cache[i]键对应的值是一个对象,这个对象的键是name,这样一个element就可以存储多个值了,说的很绕,举个例子
(“#test1”).data(“data1”,12);(“#test1”).data(“data2”,12);
(“#test2”).data(“data3”,12);
//二个元素新增一个属性elem[ expando ] 是下面这样(“#test1”)[expando] = 2;
$(“#test2”)[expando] = 3;
//二个元素的elem[ expando ]对应cache存储是这样的
cache :{
2 : {“data1”:12,”data2”,12},
3 : {“data3”,12}
}
javascript
因为cache这个对象的键id是通过jQuery的全局变量uuid获取的,uuid是一个自增的变量,所以不会重复。
## removeData();
removeData相对应的是去移除cache对应的这个键值对,同时移除element的expando属性,源码如下
removeData: function( elem, name ) {
elem = elem == window ?
windowData :
elem;
var id = elem[ expando ];
// If we want to remove a specific section of the element's data
if ( name ) {
if ( jQuery.cache[ id ] ) {
// Remove the section of cache data
delete jQuery.cache[ id ][ name ]; //删除element对应属性
// If we've removed all the data, remove the element's cache
name = "";
for ( name in jQuery.cache[ id ] )
break;
if ( !name )
jQuery.removeData( elem );
}
// Otherwise, we want to remove all of the element's data
} else {
// Clean up the element expando
try {
delete elem[ expando ]; //删除element对应属性
} catch(e){
//彩蛋,ie下不支持delete,但支持removeAttribute
// IE has trouble directly removing the expando
// but it's ok with using removeAttribute
if ( elem.removeAttribute )
elem.removeAttribute( expando );
}
// Completely remove the data cache
delete jQuery.cache[ id ];
}
},
“`