2013-02-10 47 views
5

這段代碼最能表明我的困惑。爲什麼jQuery的.data方法表現得像這樣? (可能的bug?)

var nativeObj, jWrapped, jSelector; 

//WIAT = "What I Am Thinking" 
nativeObj = $('#tableTab') [0]; //WIAT: unwrap the jQuery object created by the selector and get the native DOM object 
jWrapped = $(nativeObj); //WIAT: wrap up the native DOM object again... should be equal to $('#tableTab') 
jSelector = $('#tableTab'); //WIAT: pass the jQuery object as reference to jSelector variable 

// set the data with jQuery's .data method 
$.data(jWrapped, 'key', { test: 12 }); //WIAT: will be equivalant to using $('#tableTab') and should attach the data to it 
$.data($('#tableTab') [0], 'key', { test: 34 }); //WIAT: using the native DOM obj, it shouldn't work with this, since it doesn't specify in the docs 
$.data($('#tableTab') , 'key', { test: 56 }); //WIAT: should rewrite the data in the element to { key: { test: 56} } 

console.log($.data (jWrapped)); // {key:{test:12}} 
console.log($.data (jWrapped[0])); // {key:{test:34}} 
console.log($.data (nativeObj)); // {key:{test:34}} 
console.log($.data ($(nativeObj), 'test')); // undefined 
console.log($.data ($('#tableTab') [0])); // {key:{test:34}} 
console.log($.data ($('#tableTab') , 'test')); // undefined 

哇,等待,這是怎麼回事

1.我爲什麼得到不同的結果?我只使用了1個選擇器並引用了一個元素。

2.爲什麼不是對象引用jWrapped$('#tableTab')的對象產生相同的結果?

3.此外jWrappedjWrapped[0]正在生產不同的結果?前者是一個jQuery包裝對象,後者是一個本地DOM對象。本質上他們是引用相同的元素與不同的結果

//Now let's see what's inside the objects 
console.log($('#tableTab') [0]); // [object HTMLDivElement]   
console.log(nativeObj); // [object HTMLDivElement] 
console.log($(nativeObj)); // {0:({}), context:({}), length:1} 
console.log(jWrapped); // {0:({}), context:({}), length:1, jQuery182021025872972076787:{toJSON:(function() {}), data:{key:{test:12}}}} 
console.log($('#tableTab')); // {length:1, 0:({}), context:({}), selector:"#tableTab"} 
console.log(jSelector); // {length:1, 0:({}), context:({}), selector:"#tableTab"} 

nativeObj == $('#tableTab') [0]這是我所期待的

哇,這很奇怪,爲什麼不jWrapped == $(nativeObj)

好,jSelector = $('#tableTab')這也是我所期待的

鑑於這個數據,我推斷出$。數據必須接受本地DOM元素,但是

$('#tableTab').data('key' , { test: 78 }); 
console.log($('#tableTab').data('key')); // 78 

嗯對不起先生控制檯...不酷的人。

好吧我是皇家困惑和沮喪,我討厭jQuery和我恨Javascript和我討厭IE ... 好吧,我只是討厭IE瀏覽器,但這是另一個故事。爲什麼jQuery表現得如此奇怪?用IE瀏覽器太多我認爲...

我的猜測是它與$ .data在jQuery中的工作方式有關,它實際上並沒有將數據附加到元素,而是 將數據存儲在它自己的對象並基於解析傳遞的數據來引用數據。我有沒有發現錯誤?

幫助。

我也看過How does jQuery .data() work?,雖然它提供了一些很好的信息,但它仍然不能回答這裏發生的事情,這是我真正的問題。雖然它確實證實了我的想法,即沒有數據存儲在元素中,而是存儲在jQuery對象中。

回答

3

看着Chrome開發工具的源,我發現周圍的線1564這一評論,在1.9版本(GitHub source here 17行功能internalData內)

// Only DOM nodes need the global jQuery cache; JS object data is 
// attached directly to the object so GC can occur automatically 

那麼,什麼發生在這裏,就是當你通過nativeObj,它會將數據存儲在$ .cache中,否則它會將值存儲到傳入的jQuery對象中。

看看這個小提琴: http://jsfiddle.net/tomprogramming/SNqwh/

我發到你原來的例子進行一些更改。首先是我傳入您在頂部設置的對象。第二個是你在查詢一個名爲「test」的數據的對象,但那不會永遠存在 - 你正在存儲一個碰巧有一個名爲test的屬性的對象 - 在「key」屬性下, 。

在您的日誌語句的末尾,我添加了自己的,而不是使用$.data的面向對象特性。每一次,我都會得到相同的結果。我的猜測是,它使用每個jQuery對象的底層dom節點來訪問全局緩存,在你的情況下,它的值爲{test:34}

我確實認爲這是意想不到的行爲,因爲它對新手用戶來說顯然是選擇了相同的元素,但我相信這只是$.data$(selector).data()之間區別的下劃線。後者總是使用底層dom節點(因此總是「正確」),而前者將使用傳入的jQuery對象(如果可用)。

編輯:this fiddle再次強調了區別。我使用$(selector).data()設置了該值,然後用$.data再次將其拉出。用於原始對象的「緩存」沒有改變(作爲對象本身),但是全局緩存對於底層DOM節點具有改變。

這裏的課本:始終使用DOM節點或$().data。這是「最一致的」

+0

+1在GitHub中查看註釋。這確實解釋了爲什麼我可以通過一個看似相似的jQuery參考獲得不同的結果。然而,爲什麼'jWrapped'和'$('#tableTab')'有不同的表現?這兩個都是jQuery對象是否正確?但如果我使用格式'$ .data($('#tableTab'))'這對我來說似乎很奇怪,我無法獲取任何數據。b/c jQuery通常接受選擇器來代替元素。可能是b/c'jWrapped'是一個已經初始化的對象,而'$('#tableTab')'不是?似乎反直覺b/c'$('#tableTab).data()'工作。你也可以詳細說明你的'在這裏得到的教訓'。 – Klik 2013-02-10 07:14:31

+0

那最後一把小提琴確實給了我一些啓發。 jSelector.data('key',{test:57});'和'jWrapped.data('key',{test:116});''jSelector和jWrapped都是jQuery對象,每個都有它自己的一組數據。這只是解決這個謎,除了,爲什麼不$ .data($('#tableTab'))的工作?此外,我假設$()返回一個jQuery對象,所以它將與傳遞一個jQuery對象相同。 – Klik 2013-02-10 07:26:48

+0

試圖遵循代碼路徑,它看起來像兩個方法甚至不遵循相同的代碼路徑。一個直接進入'internalData',另一個在jQuery插件中跳轉。這對jQuery來說絕對是奇怪的行爲。要回答第二個問題,我只能回答:並非所有的jQuery對象都是相同的:http://jsfiddle.net/tomprogramming/NqR2V/。雖然底層節點是相同的,但是對象本身是不同的。 – 2013-02-10 21:57:27

相關問題