1、从用户调用的入口开始阅读,因为这是我们比较熟悉的部分(主要做参数的调整,根据不同的完成不同的功能)
// 进入jQuery Data模块的入口 使用方法有三种,不传参,传一个参,传两个参。示例$("div").data("name", "value")
// 如果不传参则返回该元素上的所有数据,传一个参数则返回该元素上对应的属性值,传两个参数则为该元素绑定该属性并赋值
data: function( key, value ) {
var attrs, name,
// 取出jQuery对象中的第一个DOM对象,数据是存储在DOM对象上而不是jQuery对象上。
elem = this[ 0 ],
i = 0,
data = null;
// key === undefined 说明一个参数都没有传入,$("div").data(),此时取出绑定在该jQuery对象中第一个DOM对象上的所有数据
if ( key === undefined ) {
// 如果该jQuery对象中至少包含一个DOM对象
if ( this.length ) {
// 调用Data对象的get方法,取得存在elem上所有的数据
data = data_user.get( elem );
// 如果elem是元素节点 并且elem上没有存"hasDataAttrs",使用内部Data对象为什么?
if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
attrs = elem.attributes;
//遍历elem的所有属性
for ( ; i < attrs.length; i++ ) {
name = attrs[ i ].name;
// 如果该属性名是以"data-"开头的.
if ( name.indexOf( "data-" ) === 0 ) {
// 去掉"data-"并将其后的字符串转变成驼峰式的
name = jQuery.camelCase( name.slice(5) );
// 将DOM元素的属性上存储的数据存进Data的cache中
dataAttr( elem, name, data[ name ] );
}
}
// 存入另一个Data对象的cache中,用来告诉上一个if语句,不需要再进行读DOM上的属性了。
data_priv.set( elem, "hasDataAttrs", true );
}
}
return data;
}
// 如果key是一个对象,说明用户是在以键值对的形式传入的参数
if ( typeof key === "object" ) {
// 调用set方法,内部是吧key这个对象的键为键,值为值存入到cache中
return this.each(function() {
data_user.set( this, key );
});
}
// 一个统一的接口,根据参数做出不同的响应
return jQuery.access( this, function( value ) {
var data,
// 将key转换为驼峰式
camelKey = jQuery.camelCase( key );
// 如果调用data方法的对象中存在DOM元素并且没有传入value
if ( elem && value === undefined ) {
// 从外部使用的data对象中取出响应key的value
data = data_user.get( elem, key );
// 如果存在这个value就返回它
if ( data !== undefined ) {
return data;
}
// 如果没有取到,尝试将key转换成驼峰式再去取一次(DOM属性中的data-属性的存储方式)
data = data_user.get( elem, camelKey );
if ( data !== undefined ) {
return data;
}
// 如果仍然没取到,调用dataAttr方法取(还没看,感觉是从DOM上取),
data = dataAttr( elem, camelKey, undefined );
if ( data !== undefined ) {
return data;
}
// 尝试了很多方法都没返回,则直接返回undefined
return;
}
// 没明白它要干嘛
this.each(function() {
var data = data_user.get( this, camelKey );
data_user.set( this, camelKey, value );
if ( key.indexOf("-") !== -1 && data !== undefined ) {
data_user.set( this, key, value );
}
});
}, null, value, arguments.length > 1, null, true );
},