1. ホーム
  2. jquery

[解決済み] jquery データセレクタ

2022-04-17 03:42:30

質問

要素の .data() オブジェクトを作成します。最低限、セレクタを使ってトップレベルのデータプロパティを選択したいのですが、おそらくこのような感じです。

$('a').data("category","music");
$('a:data(category=music)');

あるいは、セレクタは通常の属性セレクタの形式になるでしょう。

$('a[category=music]');

または属性形式でありながら、それを示す指定子で .data() :

$('a[:category=music]');

見つけたのは James Padolseyの実装 はシンプルで良い感じです。上のセレクタのフォーマットは、このページで紹介されている方法を反映しています。また、次のようなものもあります。 シズルパッチ .

なぜか、jQuery 1.4では、jqueryの値に対するセレクタがサポートされるという記事を少し前に読んだ記憶があります。 .data() オブジェクトを作成しました。しかし、今、探してみても見つかりません。もしかしたら、私が見たのは機能要望だけだったのかもしれません。サポートがあるのに、私が見ていないだけなのでしょうか?

理想を言えば、ドット記法によるdata()のサブプロパティをサポートしたいです。このように。

$('a').data("user",{name: {first:"Tom",last:"Smith"},username: "tomsmith"});
$('a[:user.name.first=Tom]');

また、複数のデータセレクタに対応し、指定したすべてのデータセレクタを持つ要素のみを検索できるようにしたいです。通常のjqueryのマルチプルセレクタは、OR演算を行います。 例えば、以下のような感じです。 $('a.big, a.small')a のどちらかのクラスを持つタグを使用します。 big または small ). 私はANDを探しているのですが、おそらくこんな感じです。

$('a').data("artist",{id: 3281, name: "Madonna"});
$('a').data("category","music");
$('a[:category=music && :artist.name=Madonna]');

最後に、データセレクタで比較演算子や正規表現機能が利用できれば最高です。そこで $(a[:artist.id>5000]) が可能です。おそらくこの多くは filter() しかし、シンプルなセレクタのフォーマットがあればいいと思います。

これを実現するために、どのようなソリューションがあるのでしょうか?JameのPadolseyのものが現時点でのベストソリューションなのでしょうか?私の懸念は、主にパフォーマンスに関してですが、サブプロパティのドットノテーションや複数のデータセレクタのような追加機能にもあります。これらのことをサポートする、あるいは何らかの点でより優れた他の実装があるのでしょうか?

解決方法は?

新しい data セレクタを使用すると、ネストされたクエリやAND条件を実行できるようになります。 使い方は

$('a:data(category==music,artist.name==Madonna)');

というパターンがあります。

:data( {namespace} [{operator} {check}]  )

operator" と "check" はオプションです。そのため、もし :data(a.b.c) をチェックするだけです。 真偽 a.b.c .

以下のコードで、利用可能な演算子を確認することができます。その中で ~= で、正規表現によるテストが可能です。

$('a:data(category~=^mus..$,artist.name~=^M.+a$)');

いくつかのバリエーションでテストしてみましたが、かなりうまくいくようです。近々Githubのレポに追加すると思うので、楽しみにしていてください(テストスイートを含む)。

コードです。

(function(){

    var matcher = /\s*(?:((?:(?:\\\.|[^.,])+\.?)+)\s*([!~><=]=|[><])\s*("|')?((?:\\\3|.)*?)\3|(.+?))\s*(?:,|$)/g;

    function resolve(element, data) {

        data = data.match(/(?:\\\.|[^.])+(?=\.|$)/g);

        var cur = jQuery.data(element)[data.shift()];

        while (cur && data[0]) {
            cur = cur[data.shift()];
        }

        return cur || undefined;

    }

    jQuery.expr[':'].data = function(el, i, match) {

        matcher.lastIndex = 0;

        var expr = match[3],
            m,
            check, val,
            allMatch = null,
            foundMatch = false;

        while (m = matcher.exec(expr)) {

            check = m[4];
            val = resolve(el, m[1] || m[5]);

            switch (m[2]) {
                case '==': foundMatch = val == check; break;
                case '!=': foundMatch = val != check; break;
                case '<=': foundMatch = val <= check; break;
                case '>=': foundMatch = val >= check; break;
                case '~=': foundMatch = RegExp(check).test(val); break;
                case '>': foundMatch = val > check; break;
                case '<': foundMatch = val < check; break;
                default: if (m[5]) foundMatch = !!val;
            }

            allMatch = allMatch === null ? foundMatch : allMatch && foundMatch;

        }

        return allMatch;

    };

}());