1

属性を.filterチェックしている多数の要素に対して関数を使用したいのですが、それらはメソッドによって設定されています。data-*.data

問題は、jQuery セレクターが常に元の値を使用することです。を使用してデータ値を設定して$('whatever').data('key', newValue)からセレクターを使用しようとすると$('[data-key=newValue]')、何も見つかりません。

ここに私のテストHTMLがあります:

<div id="test" data-dummy="foo"></div>
<div id="result"</div>

それで:

$('#test').data('dummy', 'bar');

$('#result').
    append('<div>Where dummy=foo: ' + $('[data-dummy="foo"]').length + '</div>').
    append('<div>Where dummy=bar: ' + $('[data-dummy="bar"]').length + '</div>');

出力:

ダミー = フー :1

ダミー = バー :0

セレクターエンジンの場合、元の値のみがセレクターで使用されるようです。

更新- 最初の回答に乾杯します。これは実際には意図的なものです。.data値で始まりdata-*ますが、独自のコピーを設定します。.data(へのすべての呼び出しを への呼び出しに置き換えたくありません.attr('data-' +

これを回避するために.filter関数を使用していますが、このフィルターは多数の要素に対して実行されるため、一致ごとに新しい jQuery オブジェクトを作成したくありません。この種の状況のた​​めに、jQuery はいくつかのグローバル関数を提供します。

$.data(element,基本的にの代わりにを使用できるはずです$(element).data(が、これも機能しませ$.data(element,undefined

だから私のコードは次のようになります.filter(function(){return $.data(this, key) === value;})

ただし、それは jQuery オブジェクトが初期化される前のみのようです。

var domEle = document.getElementById('test');
var globalBefore = $.data(domEle, 'dummy');
var first = $(domEle).data('dummy');
var globalAfter = $.data(domEle, 'dummy');

$('#result').
    append('<div>$.data before: ' + globalBefore + '</div>').
    append('<div>new $(): ' + first + '</div>').
    append('<div>$.data after: ' + globalAfter + '</div>');

出力:

前の $.data: 未定義

新しい $(): フー

$.data after: foo

変。問題は、それを回避できるかどうかです。$テストされたノードごとにオブジェクトを作成せずに、新しいオブジェクトで起こっていることを初期化する方法はありますか?

JS Fiddle デモ: http://jsfiddle.net/kU4th/

4

3 に答える 3

1

jQuery はデータ属性を読み取りますが、データは属性とは別に保存されます。要素にデータを設定しても、属性には影響しません。

属性も変更する場合は、メソッドattrの代わりにメソッドを使用して値を設定する必要がありますdata

$('#test').attr('data-dummy', 'bar');

data-dummyこれにより、要素の属性と要素の値の両方が設定されdata('dummy')ます。

于 2013-08-08T08:44:50.007 に答える
1

これはバグではなく、本当に紛らわしく設計された動作です。

問題は、jQuery セレクターが元の値を使用しているように見えることです。$('whatever').data('key', newValue) を使用してデータ値を設定し、セレクター $('[data-key=newValue]') を使用しようとすると、何も見つかりません。

これは、属性を設定dataすることはなく、それらから自身を初期化するだけだからです。それは非対称です(それらから読み取りますが、それらに書き込みません)。 data-*

実際に属性を更新するには、 を使用しますattr。たとえば、次の代わりに:

$('whatever').data('key', newValue);

あなたが必要

$('whatever').attr('data-key', newValue);

データ属性の両方を設定する場合:

$('whatever').data('key', newValue).attr('data-key', newValue);

dataオブジェクトの jQuery 管理キャッシュを使用して、データのキーと値のペアを要素に関連付けます。data要素のデータ キャッシュにまだ存在しないキーを要求すると、そのキーが属性と一致するかどうかが確認され、一致する場合data-*はその値でデータ キャッシュが初期化されます。その時点で、と属性の間にそれ以上の接続はありません。datadata-*

属性に書き戻さない理由dataは、おそらく少なくとも部分的には、を介して何でもdata保存できるという事実によるものですが、もちろん属性値は常に文字列です。たとえば、次のようにします。

$("whatever").data('key', {
    nice:   "complex",
    obj:    "here",
    answer: 42,
    when:   new Date()
});

...その後、後で$("whatever").data('key')そのオブジェクトを返します。そのオブジェクトは属性に格納できません。

この驚くべきデザインにやけどを負ったのは、あなたが最初ではありません。:-)


$.data(element基本的に、 の代わりに,を使用できるはずですが$(element).data(、これも機能しません: $.data(element, を返しますundefined

右。のドキュメントに$.dataは、その理由が示されています。

注:これは低レベルのメソッドです。より便利.data()な もご用意しています。

HTML5 の data-* 属性について: この低レベル メソッドは、より便利.data()な方法で既に data-* 属性を取得していない限り、data-* 属性を取得しません。

dataへの呼び出しを への呼び出しに置き換えたくないと言っていましたattrが、それが最良の状況のように思われるのでdata-*、セレクターでこれらの属性を実際に使用できます。

または、これを行うことができます:

matchingElements.filter(function(){
    return ($.data(this, key) || this.getAttribute('data-' + key)) === value;
});

...最初にデータを見て、偽の値 ( 、、、、または)dataが返された場合は、代わりに要素から属性を取得します。それをちょうどに制限したい場合:undefinednull""falseNaN0undefined

matchingElements.filter(function(){
    var value = $.data(this, key);
    return typeof value === "undefined" ? this.getAttribute('data-' + key) : value;
});
于 2013-08-08T08:40:20.937 に答える
1

jquery の data メソッドと HTML5 の data-* 属性はまったく別物です。

ドキュメントを参照してください:

HTML5 の data-* 属性について: この低レベルのメソッドは、より便利な .data() メソッドが既にそれらを取得していない限り、data-* 属性を取得しません。

設定した内容

$(selector).data('key', value)

あなたが取得する

var foo = $(selector).data('key')

html data-* 属性を使用する場合は、

$(selector).attr('data-key', value)

そしてそれを取得します

var foo = $(selector).attr('data-key');
于 2013-08-08T08:40:41.227 に答える