5

このコードは、私の混乱を最もよく示しています。

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' ) これも予想通り

このデータを考えると、 $.data はネイティブ DOM 要素を受け入れる必要があると推測できますが、

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

うーん、すみません、ムッシューコンソール... クールな男ではありません。

わかりました私は非常に混乱してイライラしており、jQuery が嫌いで、Javascript が嫌いで、IE が嫌いです...わかりません、IE が嫌いなだけですが、それはまた別の話です。jQuery の動作がおかしいのはなぜですか? IEを使いすぎていると思います...

私の推測では、jQuery で $.data が機能する方法と関係があり、実際にはデータを要素にアタッチするのではなく、データを独自のオブジェクトに格納し、渡されたデータの解析に基づいてデータを参照します。それ。バグを見つけましたか?

ヘルプ。

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

4

1 に答える 1

3

Chrome 開発者ツールのソースを見ると、バージョン 1.9 の 1564 行目あたりにこのコメントが見つかりました ( GitHub ソースはこちら、関数内の 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/

元の例にいくつかの変更を加えました。1 つ目は、上部に設定したオブジェクトを渡すことです。2 つ目は、「test」と呼ばれるデータの一部についてオブジェクトをクエリすることですが、それは存在しません。たまたま test と呼ばれるプロパティを持つオブジェクトを「key」のプロパティの下に格納しています。 .

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

$.data初心者ユーザーには同じ要素を選択しているように見えるため、これは予期しない動作であることに同意しますが、これはとの違いの単なる下線だと思います$(selector).data()。後者は常に基礎となる dom ノードを使用します (したがって、常に「正しい」) のに対して、前者は渡された jQuery オブジェクトが使用可能な場合はそれを使用します。

EDIT:このフィドルは、違いを強調しています。で値を設定し$(selector).data()、 で再度引き出し$.dataます。元のオブジェクトに使用される「キャッシュ」(オブジェクト自体) は変更されていませんが、基になる DOM ノードのグローバル キャッシュは変更されています。

ここでの教訓: 常に DOM ノードまたは$().data. それが「最も一貫性がある」

于 2013-02-10T06:50:20.203 に答える