2013-02-10 9 views
5

このコードは私の混乱を最もよく示しています。jQueryの.dataメソッドがこのように動作するのはなぜですか? (考えられるバグ?)

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つしか使用せず、1つの要素を参照しています。

2.オブジェクト参照がありませんjWrappedと同じ結果をもたらすオブジェクトは$('#tableTab')ですか?

3さらに、jWrappedおよびjWrapped[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')、私はウムはムッシュコンソール恐れ入りますが

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

、その$の.dataセクションは、ネイティブDOM要素を受け入れなければならない外挿します...クールな男じゃない。

オクラホマは混乱して困っていて、jQueryが嫌い、Javascriptが嫌い、IEが嫌い... いいえ、私はIEを嫌いですが、それは別の話です。 jQueryの動作が奇妙なのはなぜですか?私はIEとのやりとりがあまりにも多いと思っています...

$ .dataはjQueryで動作し、実際には要素にデータを添付しないで、むしろ はデータを格納します独自のオブジェクトを参照し、渡されたデータの解析に基づいてデータを参照します。私はバグを見つけましたか?

ヘルプ。

また、私はHow does jQuery .data() work?を見ましたが、いくつかの良い情報を提供していましたが、ここで起こっていることはまだ答えられません。これは本当の質問です。要素にはデータが格納されていないが、jQueryオブジェクトには格納されていないという私の考えを確認します。

答えて

3

Chromeデベロッパーツールでソースを見ると、私はバージョン1.9で、ライン1564の周りにこのコメントを見つけました(GitHub source here、機能internalData内の17行目)

// 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/

私はあなたの元の例にいくつかの変更を加えました。最初は、あなたが上に設定したオブジェクトを渡します。もう1つは、 "test"という名前のデータのオブジェクトをクエリすることですが、そこには存在しません。 "key"のプロパティの下で、testというプロパティを持つオブジェクトを格納しています。 。

ログステートメントの最後には、オブジェクト指向の性質$.dataを使用して自分自身を追加しました。毎回、私は同じ結果を返します。私の推測では、各jQueryオブジェクトの基になるdomノードを使ってグローバルキャッシュにアクセスしています。その場合は、{test:34}という値があります。

初心者ユーザーに同じ要素を選択しているように思われるので、予期しない動作であることに同意しますが、これは$.data$(selector).data()の違いのアンダースコアに過ぎません。後者は常に、下にあるdomノードを使用します(したがって、常に正しいです)。前者は、渡すjQueryオブジェクトを使用します(使用可能な場合)。

EDIT:this fiddleもまた違いを示しています。 $(selector).data()を使用して値を設定し、$.dataでもう一度引き出します。元のオブジェクトに使用された 'キャッシュ'は変更されていません(オブジェクト自体である)が、基本的なDOMノードに対してはグローバルキャッシュがあります。

ここでのレッスン:常にDOMノード、つまり$().dataを使用してください。それはGitHubのコメントを見るための "最も一貫性のある"

+0

+1です。それはなぜ私が「一見」類似したjQueryリファレンスで異なる結果を得ることができるのかを説明します。しかし、なぜ 'jWrapped'と' $( '#tableTab')の動作が違うのですか?どちらもjQueryオブジェクトは正しいですか? '$ .data($( '#tableTab'))'という形式を使用するとデータが得られません。b/c jQueryは通常、要素の代わりにセレクタを受け入れます。 '$( '#tableTab')'はありませんが、 'jWrapped'は既に初期化されたオブジェクトです。直感的なb/c '$( '#tableTab).data()'が動作するようです。また、あなたはあなたの「レッスン」を詳しく説明します。 – Klik

+0

最後のフィドルが私に何かを教えてくれました。 jSelectorとjWrappedの両方がjQueryオブジェクトであり、それぞれが持っているものはjQueryオブジェクトであり、jSelector.data( 'key'、{test:57});および 'jWrapped.data( 'key'、{test:116});それ自身のデータセット。 $ .data($( '#tableTab'))が動作しないのはなぜですか?さらに、$()はjQueryオブジェクトを返すと仮定したので、jQueryオブジェクトを渡すのと同じです。 – Klik

+0

コードパスに従うことを試みると、同じコードパスに従っていない2つの方法があるように見えます。 1つは 'internalData'に直接入ります。もう1つはjQueryプラグインの中で少しジャンプします。これは間違いなくjQueryの動作です。 2番目の質問に答えるために、私は答えます:すべてのjQueryオブジェクトが等しく作成されているわけではありません:http://jsfiddle.net/tomprogramming/NqR2V/。基本となるノードは同じですが、オブジェクト自体は異なります。 –

関連する問題