JQuery data API实现代码分析
JQuery data 接口是什么?
.data()
Store arbitrary data associated with the matched elements or return the value at the named data store for the first element in the set of matched elements.
根據jquery官網介紹,data給存儲DOM關聯的數據, 設置數據是對$選取的所有JQuery對象, 獲取數據是對$選取的所有對象的第一個對象的存儲的數據。
設置語法格式 --- 設置單個數據 .data( key, value )? 設置一組數據 .data( obj ) :
獲取語法格式 --- 獲取單個數據 .data( key)? 設置所有數據 .data() :
????? 例子:
$( "body" ).data( "foo", 52 ); $( "body" ).data( "bar", { myType: "test", count: 40 } ); $( "body" ).data( { baz: [ 1, 2, 3 ] } ); $( "body" ).data( "foo" ); // 52 $( "body" ).data(); // { foo: 52, bar: { myType: "test", count: 40 }, baz: [ 1, 2, 3 ] }?為什么需要 data 接口?
web前端JS編程不可避免地,需要頻繁地與DOM對象打交道。 HTML標簽負責文檔的結構, JS負責文檔的行為, CSS負責文檔的樣式, JS通過document.getElementById()等接口獲取DOM對象, 除了操作DOM對象的樣式和屬性等,往往在行為邏輯上, 腳本需要記錄與DOM對象相關的數據 或者 某種狀態值, 如果在js中直接使用全局變量記錄此值, 具有很大的缺點, 首先不能直觀體現此數據與DOM對象的關系, 其次全局變量有可能會發生命名沖突。
例如,一個進度條DOM對象, 需要記錄進度百分比值, 可以將此數據使用data接口記錄到DOM對象上。
?
data 接口代碼分析- .data( key, value )? 設置單個數據
?
1、 JQuery對象的原型fn函數集合,添加了data接口,此接口判斷如果為設置數據, 即arguments.length>1, 表示具有兩個參數, 則執行紅色代碼三行, 將需要設置的DOM對象和需要設置的key和value , 傳入 JQuery對象的data接口。
JQuery對象的data接口又做了些什么?
jQuery.fn.extend({data: function( key, value ) {var i, name, data,elem = this[0],attrs = elem && elem.attributes; .....return arguments.length > 1 ? // Sets one valuethis.each(function() {jQuery.data( this, key, value );}) :// Gets one value// Try to fetch any internally stored data firstelem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;},
?
2、 jQuery.data函數分析
調用internalData函數并返回此函數的返回值。
jQuery.extend({cache: {}, ......data: function( elem, name, data ) {return internalData( elem, name, data );},?
3、 internalData 函數分析
此函數的第四個入參pvt可以忽略,執行過程有下面幾個關鍵點:
#1 對于DOM對象nodeType為 1, 則緩存cache被設置為JQuery.cache。 此緩存空間即為 每個DOM對象data數據存儲空間。
#2? 對于第一次使用data接口, 需要對DOM元素, 生成一個唯一的ID: id = deletedIds.pop() || jQuery.guid++;
#3? 然后在緩存空間 JQuery.cache中, 按照ID為下表為此DOM元素分配一個子空間: cache[ id ] = {}
#4 將此DOM子空間記錄為 thisCache = cache[ id ];
#5 為此DOM子空間再開辟明確的data子空間: thisCache.data = {}; 并將此data子空間記錄為thisCache
#6 設置數據 : thisCache[ jQuery.camelCase( name ) ] = data;
function internalData( elem, name, data, pvt /* Internal Use Only */ ) {............
var ret, thisCache,internalKey = jQuery.expando,// We have to handle DOM nodes and JS objects differently because IE6-7// can't GC object references properly across the DOM-JS boundaryisNode = elem.nodeType,// Only DOM nodes need the global jQuery cache; JS object data is// attached directly to the object so GC can occur automaticallycache = isNode ? jQuery.cache : elem, ...........if ( !id ) {// Only DOM nodes need a new unique ID for each element since their data// ends up in the global cacheif ( isNode ) {id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;} else {id = internalKey;}}if ( !cache[ id ] ) {// Avoid exposing jQuery metadata on plain JS objects when the object// is serialized using JSON.stringifycache[ id ] = isNode ? {} : { toJSON: jQuery.noop };} ............thisCache = cache[ id ];// jQuery data() is stored in a separate object inside the object's internal data// cache in order to avoid key collisions between internal data and user-defined// data.if ( !pvt ) {if ( !thisCache.data ) {thisCache.data = {};}thisCache = thisCache.data;}if ( data !== undefined ) {thisCache[ jQuery.camelCase( name ) ] = data;} ...............
}
?
data 接口代碼分析- .data( key)? 獲取單個數據
1、此接口判斷如果為獲取數據, 即arguments.length>1為false, 表示具有一個參數, 則返回 下面函數調用返回的結果: dataAttr( elem, key, jQuery.data( elem, key ) )
dataAttr又做了些什么?
jQuery.fn.extend({data: function( key, value ) {var i, name, data,elem = this[0], attrs = elem && elem.attributes; ..... return arguments.length > 1 ? // Sets one value this.each(function() { jQuery.data( this, key, value ); }) : // Gets one value // Try to fetch any internally stored data first elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; },
?
2、 dataAttr 分析
查看注釋, 此函數為 data不存在的情況下, 查HTML中 data-開頭的相同屬性值, 此處可以不用分析。
下面還是分析下下面函數調用執行, jQuery.data( elem, key ) function dataAttr( elem, key, data ) {// If nothing was found internally, try to fetch any// data from the HTML5 data-* attributeif ( data === undefined && elem.nodeType === 1 ) {?
3、 jQuery.data( elem, key ) 獲取單個數據
調用internalData函數并返回此函數的返回值。
我們下面分析 internalData函數第三個參數 data為空的情況。
jQuery.extend({cache: {}, ......data: function( elem, name, data ) {return internalData( elem, name, data );},?
4、 internalData 函數分析
此函數的第四個入參pvt可以忽略:
可以看到,對于獲取單個數據情況, 還是從 JQuery.cache[DOM-ID].data中查找, 即下面這一句:
ret = thisCache[ name ]; function internalData( elem, name, data, pvt /* Internal Use Only */ ) {...............var ret, thisCache,internalKey = jQuery.expando,// We have to handle DOM nodes and JS objects differently because IE6-7// can't GC object references properly across the DOM-JS boundaryisNode = elem.nodeType,// Only DOM nodes need the global jQuery cache; JS object data is// attached directly to the object so GC can occur automaticallycache = isNode ? jQuery.cache : elem,// Only defining an ID for JS objects if its cache already exists allows// the code to shortcut on the same path as a DOM node with no cacheid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
.................
thisCache = cache[ id ];// jQuery data() is stored in a separate object inside the object's internal data// cache in order to avoid key collisions between internal data and user-defined// data.if ( !pvt ) {if ( !thisCache.data ) {thisCache.data = {};}thisCache = thisCache.data;} .................// Check for both converted-to-camel and non-converted data property names// If a data property was specifiedif ( typeof name === "string" ) {// First Try to find as-is property dataret = thisCache[ name ];// Test for null|undefined property dataif ( ret == null ) {// Try to find the camelCased propertyret = thisCache[ jQuery.camelCase( name ) ];}} else {ret = thisCache;}return ret; }
?
轉載于:https://www.cnblogs.com/lightsong/p/4020836.html
總結
以上是生活随笔為你收集整理的JQuery data API实现代码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 也是醉了。。。
- 下一篇: AMD宣布裁员7% 约710员工将失去工