sélecteur de données jquery

Je dois sélectionner des éléments en fonction des valeurs stockées dans l’object .data() un élément. Au minimum, j’aimerais sélectionner des propriétés de données de premier niveau à l’aide de sélecteurs, peut-être comme ceci:

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

Ou peut-être que le sélecteur serait au format sélecteur d’atsortingbut normal:

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

Ou dans le format d’atsortingbut, mais avec un spécificateur pour indiquer qu’il est dans .data() :

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

J’ai trouvé que l’implémentation de James Padolsey était simple, mais bonne. Les formats de sélecteur au-dessus des méthodes de miroir affichées sur cette page. Il y a aussi ce patch Sizzle .

Pour une raison quelconque, je me rappelle avoir lu il y a quelque temps que jQuery 1.4 inclurait la prise en charge des sélecteurs sur les valeurs de l’object jquery .data() . Cependant, maintenant que je le cherche, je ne le trouve pas. Peut-être que c’était juste une demande de fonctionnalité que j’ai vue. Y a-t-il un soutien pour cela et je ne le vois pas?

Idéalement, je voudrais soutenir les sous-propriétés dans data () en utilisant la notation par points. Comme ça:

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

Je voudrais également prendre en charge plusieurs sélecteurs de données, où seuls les éléments avec TOUS les sélecteurs de données spécifiés sont trouvés. Le sélecteur multiple jquery normal effectue une opération OU. Par exemple, $('a.big, a.small') sélectionne a balise avec une classe big ou small . Je cherche un AND, peut-être comme ça:

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

Enfin, il serait bon que les opérateurs de comparaison et les fonctionnalités regex soient disponibles sur les sélecteurs de données. Donc $(a[:artist.id>5000]) serait possible. Je me rends compte que je pourrais probablement faire beaucoup de choses en utilisant filter() , mais ce serait bien d’avoir un format de sélecteur simple.

Quelles solutions sont disponibles pour ce faire? Le Padolsey de Jame est-il la meilleure solution en ce moment? Mon souci concerne principalement les performances, mais aussi les fonctionnalités supplémentaires telles que la notation par sous-propriété et les sélecteurs de données multiples. Existe-t-il d’autres implémentations qui supportent ces choses ou sont meilleures d’une certaine manière?

J’ai créé un nouveau sélecteur de data qui devrait vous permettre d’effectuer des requêtes nestedes et des conditions AND. Usage:

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

Le modèle est le suivant:

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

“opérateur” et “vérification” sont facultatifs. Donc, si vous avez seulement :data(abc) il vérifiera simplement la véracité de abc .

Vous pouvez voir les opérateurs disponibles dans le code ci-dessous. Parmi ceux-ci, il y a ~= qui permet de tester les regex:

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

Je l’ai testé avec quelques variantes et cela semble bien fonctionner. Je vais probablement append ceci sous forme de repo Github prochainement (avec une suite de tests complète), alors faites attention!

Le code:

 (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; }; }()); 

En ce moment je sélectionne comme ceci:

 $('a[data-atsortingbute=true]') 

Cela semble fonctionner correctement, mais ce serait bien si jQuery était capable de sélectionner par cet atsortingbut sans le préfixe “data-“.

Je n’ai pas testé cela avec des données ajoutées à des éléments via jQuery de manière dynamic, ce qui pourrait être la cause de cette méthode.

Vous pouvez également utiliser une fonction de filtrage simple sans aucun plugin. Ce n’est pas exactement ce que vous voulez, mais le résultat est le même:

 $('a').data("user", {name: {first:"Tom",last:"Smith"},username: "tomsmith"}); $('a').filter(function() { return $(this).data('user') && $(this).data('user').name.first === "Tom"; }); 

Je tiens à vous avertir que $('a[data-atsortingbute=true]') ne fonctionne pas, selon la réponse d’Ashley, si vous avez attaché des données à un élément DOM via la fonction data ().

Cela fonctionne comme vous vous y attendriez si vous ajoutiez un attr-data réel dans votre code HTML, mais jQuery stocke les données en mémoire, donc les résultats obtenus avec $('a[data-atsortingbute=true]') être correct.

Vous devrez utiliser le plug-in de données http://code.google.com/p/jquerypluginsblog/ , utiliser la solution de filter de Dmisorting ou faire un $ .each sur tous les éléments et vérifier itérativement

Il y a un plugin filtre :data() qui fait exactement ça 🙂

Quelques exemples basés sur votre question:

 $('a:data("category=music")') $('a:data("user.name.first=Tom")'); $('a:data("category=music"):data("artist.name=Madonna")'); //jQuery supports multiple of any selector to ressortingct further, //just chain with no space in-between for this effect 

La performance ne va pas être très grande par rapport à ce qui est possible , en sélectionnant le $._cache et en récupérant les éléments correspondants est de loin le plus rapide, mais beaucoup plus rond et pas très “jQuery-ey” en termes de vous arrivez à des choses (vous arrivez généralement du côté de l’élément). Au sumt de ma tête, je ne suis pas sûr que ce soit le plus rapide puisque le processus de passage de l’ID unique à l’élément est en soi complexe en termes de performances.

Le sélecteur de comparaison que vous avez mentionné sera préférable dans un .filter() , il n’ya pas de support intégré pour cela dans le plug-in, mais vous pouvez l’append sans trop de problèmes.

Vous pouvez définir un atsortingbut data-* sur un elm en utilisant attr() , puis sélectionner en utilisant cet atsortingbut:

 var elm = $('a').attr('data-test',123); //assign 123 using attr() elm = $("a[data-test=123]"); //select elm using atsortingbute 

et maintenant pour cet orme, à la fois attr() et data() donneront 123 :

 console.log(elm.attr('data-test')); //123 console.log(elm.data('test')); //123 

Cependant, si vous modifiez la valeur à 456 en utilisant attr() , data() sera toujours 123 :

 elm.attr('data-test',456); //modify to 456 elm = $("a[data-test=456]"); //reselect elm using new 456 atsortingbute console.log(elm.attr('data-test')); //456 console.log(elm.data('test')); //123 

Donc, si je comprends bien, il semble que vous devriez éviter de mélanger les commandes attr() et data() dans votre code si vous ne devez pas le faire. Parce que attr() semble correspondre directement au DOM alors que data() interagit avec la ‘mémoire’, bien que sa valeur initiale puisse provenir du DOM. Mais le point essentiel est que les deux ne sont pas forcément synchronisés.

Alors faites juste attention.

En tout cas, si vous ne modifiez pas l’atsortingbut data-* dans le DOM ou dans la mémoire, vous n’aurez aucun problème. Dès que vous commencez à modifier les valeurs, vous rencontrez des problèmes potentiels.

Merci à @Clarence Liu pour la réponse de @ Ash, ainsi que ce post .

 $('a[data-category="music"]') 

Ça marche. Voir Sélecteur d’égalité des atsortingbuts [nom = “valeur”] .

Si vous utilisez également jQueryUI, vous obtenez une version (simple) du sélecteur :data qui vérifie la présence d’un élément de données, vous pouvez donc faire quelque chose comme $("div:data(view)") , ou $( this ).closest(":data(view)") .

Voir http://api.jqueryui.com/data-selector/ . Je ne sais pas depuis combien de temps ils l’ont, mais c’est là maintenant!

Voici un plugin qui simplifie la vie https://github.com/rootical/jQueryDataSelector

Utilisez-le comme ça:

 data selector jQuery selector $$('name') $('[data-name]') $$('name', 10) $('[data-name=10]') $$('name', false) $('[data-name=false]') $$('name', null) $('[data-name]') $$('name', {}) Syntax error