17

jQueryを使用してコードを開発しており、特定のDOM要素に関連付けられたデータを保存する必要があります。html要素を使用して任意のデータを格納する方法については他にもたくさんの質問がありますが、なぜ一方のオプションを他方よりも選択するのかということに興味があります。

非常に単純化された議論のために、「興味深い」テーブルの各行に「lineNumber」プロパティを格納したいとします。

オプション1は、各DOM要素にexpandoプロパティを設定することです(「expando」という用語を正しく使用しているといいのですが)。

$('.interesting-line').each(function(i) { this.lineNumber = i; });

オプション2は、jQueryのdata()関数を使用して、プロパティを要素に関連付けることです。

$('.interesting-line').each(function(i) { $(this).data('lineNumber', i); });

サンプルコードの他の欠点を無視して、プロパティを保存する方法の1つを他の方法よりも選択する強い理由はありますか?

4

4 に答える 4

20

を使用$.dataすると、メモリリークから保護されます。

IEでは、JavaScriptオブジェクトをDOM要素のexpandoプロパティに割り当てると、そのリンクを通過するサイクルはガベージコレクションされません。javascriptオブジェクトがdomオブジェクトへの参照を保持している場合、サイクル全体がリークします。クロージャが原因で、DOMオブジェクトへの参照が非表示になる可能性があります。そのため、気付かないうちにリークする可能性があります。

jQueryデータストアは、これらのサイクルが形成されないように設定されています。これを使用すると、この方法でメモリがリークすることはありません。DOM要素にプリミティブ(文字列)を配置しているため、例はリークしません。しかし、そこにもっと複雑なオブジェクトを置くと、漏れる危険があります。

$.data心配する必要がないように使用してください。

于 2011-01-25T20:05:47.960 に答える
13

プラグインを作成する場合は、を使用する必要があります$.data。属性を頻繁に保存する必要があり、DOMにクエリを実行する必要がほとんどない場合は、を使用します$.data

5年後の更新:jQueryはexpandoプロパティセットに基づいてDOMをクエリせず、しばらくの間クエリを実行していません。したがって、を使用します$.data。実用的な使用法がない場合、DOMを汚染する理由はありません。

于 2009-07-21T17:45:33.830 に答える
2

を使用$.dataしてもDOMは変更されません。を使用する必要があります$.data。プラグインを作成する場合は$.data、構造内で異なるキーと値のペアとして各プロパティを格納するのではなく、そのオブジェクトのプロパティを使用して1つのオブジェクトを格納する必要があり$.dataます。

于 2009-07-21T16:18:41.043 に答える
0

質問を言い換えさせてください:利用可能な2つのデータバインディングオプションの実際的な違いは何ですか?

実際には3つのオプションがあります。

$(e).prop('myKey', myValue);
$(e).data('myKey', myValue);
$(e).attr('data-myKey', myValue);

注:OPは実質的にラインe.myKey = myValueと同じです。.prop()

  • 文字列以外が必要な場合は.prop()、expandoプロパティを使用します
  • DOM/CSSの透過性やHTMLシリアル化が必要な場合は.attr('data-*')
  • 両方が必要な場合は運が悪い
  • 文字列のみを使用し、DOMは必要ない場合は、長所と短所を自分で比較検討してください。
  • とは.data()→最後の2つの段落を読む

シリアル化されたHTMLを使用してデータを渡したい場合は、.attr()ソリューションが必要です。つまり、データが含まれている文字列からスニペットを作成したい、または.innerHTMLのようなものを使用するときはいつでも。.html()のようなCSSセレクターを使用する場合も同様elem[data-myKey]です。短所:文字列しか保存できません。

.data()データをDOMに表示したり、CSSインタラクションで使用したりする必要がなく、機能する可能性がある場合.prop()。それらの最大の利点は、任意のJavascript値を保持できることです

.prop()最大の欠点は、名前の衝突の可能性です。確実に名前を選択するだけで、ネイティブプロパティとして使用されることはありません。たとえばscope、キーは一部のHTML要素に存在するため、悪い考えです...

今来る.data()。他の答えはそれを誓うようです、私はそれを避けます。.prop()一般に、expandoプロパティに関連するメモリリークは過去のものであるため、これ以上の利点はありません。ただし、HTMLプロパティとの名前の衝突から保護されます。それが利点です。しかし、多くの欠点があります。

$(e).data('myKey')利用可能な場合は属性から初期化されていない値を取得し、data-myKeyそれらに対してJSON.parse()を実行し、場合によってはそれを返すか、属性の文字列値にフォールバックします。設定$(e).data('myKey', myValue)すると、属性との関係が失われますが、data-myKeyそれでもDOMおよびCSSの相互作用で示される「古い」値で存続します。さらに、使用するキー名は、名前のマングリングの可能性があります。$(e).data()つまり、そのオブジェクトのキーを介してすべてのKey-Valueを読み取ることにした場合は、異なる可能性があります。

この不安定な動作(expandoプロパティテクノロジとdata-*属性の混合)と一貫性のないget / set設計のため、私は常に避け.data().prop()ています。—幸い、これはと.attr()data-*コンプライアンスのキーを使用)で簡単に実行できます。

ネイティブプロパティとの名前の衝突を回避するために本当に使用したい場合は.data()、私のアドバイス:属性と混合せずdata-*、それらを別のものと見なし、それらとの名前の衝突を回避します。—それは意味がありますか?自動衝突回避の場合、他の場所での衝突を手動で回避する必要があります。素晴らしいデザイン。

于 2020-04-06T16:10:16.747 に答える