Sélection d'un élément par attribut de données


1020

Existe-t-il une méthode simple et directe pour sélectionner les éléments en fonction de leur dataattribut? Par exemple, sélectionnez toutes les ancres dont l'attribut de données est nommé et customerIDdont la valeur est 22.

J'hésite un peu à utiliser relou d'autres attributs pour stocker de telles informations, mais je trouve qu'il est beaucoup plus difficile de sélectionner un élément en fonction des données qui y sont stockées.



C'est ce qui m'a aidé à sélectionner tous les attributs de données (quelle que soit la valeur): $('*[data-customerID]')vous pouvez l'utiliser avec par exemple$('*[data-customerID]').each( function() { ... });
Kai Noack

Réponses:


1469
$('*[data-customerID="22"]');

Vous devriez pouvoir omettre le *, mais si je me souviens bien, selon la version de jQuery que vous utilisez, cela pourrait donner des résultats erronés.

Notez que pour la compatibilité avec l'API Selectors ( document.querySelector{,all}), les guillemets autour de la valeur d'attribut ( 22) ne peuvent pas être omis dans ce cas .

De plus, si vous travaillez beaucoup avec des attributs de données dans vos scripts jQuery, vous voudrez peut-être envisager d'utiliser le plug-in d'attributs de données personnalisés HTML5 . Cela vous permet d'écrire du code encore plus lisible en utilisant .dataAttr('foo'), et entraîne une taille de fichier plus petite après minification (par rapport à l'utilisation .attr('data-foo')).


69
Juste une note que .data ('foo') fonctionne pour obtenir la valeur d'un attribut 'data-foo' depuis jQuery 1.4.3. De plus, depuis jQuery 1.6: .data ('fooBar') obtient l'attribut 'data-foo-bar'.
James McCormack

4
@Zootius: Oui, le fichier Lisez-moi du plugin a une note à ce sujet: «Depuis jQuery 1.4.3, il est mappé .data()aux data-*attributs personnalisés par défaut, ce qui rend ce plugin redondant. Il peut néanmoins être utilisé pour les anciennes versions de jQuery. »
Mathias Bynens

Alors, comment afficher jQuery 1.4.3, sélectionner un objet par la valeur de son objet de données? Lets II voulait sélectionner dans cet exemple, tout objet avec des données pour customerID égal à 22?
Voyage le

54
De plus, si vous n'êtes intéressé que par la présence d'un attribut de données spécifique, vous pouvez le faire:$('[data-customerID]')
Darkside

7
Cela ne fonctionne pas, si le champ de données a été défini par jquery (using .data()), non?
Martin R.

330

Pour les personnes recherchant sur Google et souhaitant des règles plus générales sur la sélection avec des attributs de données:

$("[data-test]")sélectionne tout élément simple a l'attribut de données (peu importe la valeur de l'attribut). Comprenant:

<div data-test=value>attributes with values</div>
<div data-test>attributes without values</div>

$('[data-test~="foo"]')sélectionnera tout élément où l'attribut data contient foo mais ne doit pas être exact, tel que:

<div data-test="foo">Exact Matches</div>
<div data-test="this has the word foo">Where the Attribute merely contains "foo"</div>

$('[data-test="the_exact_value"]')sélectionnera tout élément dont la valeur exacte de l'attribut de données est the_exact_value, par exemple:

<div data-test="the_exact_value">Exact Matches</div>

mais non

<div data-test="the_exact_value foo">This won't match</div>

21
Bien. Notez que ~=correspond aux mots séparés par des espaces alors qu'il *=correspond à n'importe quelle sous-chaîne.
sam

Et le ^caractère?
kuba44

1
@ kuba44 en effet, vous pouvez également utiliser ^, en tant que tel $('[data-test^=foo]')dans ce cas, vous sélectionnez tout ce qui commence par foo, tel que <div data-test="foo_exact_value">ou <div data-test="food">non<div data-test="seafoo">
JDuarteDJ

Liste complète des sélecteurs d'attributs: drafts.csswg.org/selectors-3/#attribute-selectors
user1460043

142

L'utilisation $('[data-whatever="myvalue"]')sélectionnera n'importe quoi avec des attributs html, mais dans les nouvelles requêtes, il semble que si vous utilisez $(...).data(...)pour attacher des données, il utilise un navigateur magique et n'affecte pas le html, il n'est donc pas découvert par .findcomme indiqué dans la réponse précédente .

Vérifier (testé avec 1.7.2+) (voir aussi violon ): (mis à jour pour être plus complet)

var $container = $('<div><div id="item1"/><div id="item2"/></div>');

// add html attribute
var $item1 = $('#item1').attr('data-generated', true);

// add as data
var $item2 = $('#item2').data('generated', true);

// create item, add data attribute via jquery
var $item3 = $('<div />', {id: 'item3', data: { generated: 'true' }, text: 'Item 3' });
$container.append($item3);

// create item, "manually" add data attribute
var $item4 = $('<div id="item4" data-generated="true">Item 4</div>');
$container.append($item4);

// only returns $item1 and $item4
var $result = $container.find('[data-generated="true"]');

1
aha - il se trouve que quelqu'un d'autre le souligne à stackoverflow.com/questions/4191386/…
drzaus

4
et propose une solution avec .filter ici
drzaus

22
il utilise un navigateur magique et n'affecte pas le html : il n'y a rien de tel que la magie;) learningjquery.com/2011/09/using-jquerys-data-apis
Tom Sarduy


1
Si vous ajoutez un attribut de données que vous devez trouver plus tard, utilisez$item.attr('data-id', 10);
Pedro Moreira


68

Pour sélectionner toutes les ancres avec l'attribut data data-customerID==22, vous devez inclure le apour limiter la portée de la recherche à ce type d'élément uniquement. La recherche d'attributs de données dans une grande boucle ou à haute fréquence lorsqu'il y a de nombreux éléments sur la page peut entraîner des problèmes de performances.

$('a[data-customerID="22"]');

27

Exemples JS natifs

Obtenez NodeList des éléments

var elem = document.querySelectorAll('[data-id="container"]')

html: <div data-id="container"></div>

Obtenez le premier élément

var firstElem = document.querySelector('[id="container"]')

html: <div id="container"></div>

Cibler une collection de nœuds qui renvoie une liste de nœuds

document.getElementById('footer').querySelectorAll('[data-id]')

html:

<div class="footer">
    <div data-id="12"></div>
    <div data-id="22"></div>
</div>

Obtenir des éléments basés sur plusieurs valeurs de données (OR)

document.querySelectorAll('[data-section="12"],[data-selection="20"]')

html:

<div data-selection="20"></div>
<div data-section="12"></div>

Obtenir des éléments basés sur des valeurs de données combinées (AND)

document.querySelectorAll('[data-prop1="12"][data-prop2="20"]')

html:

<div data-prop1="12" data-prop2="20"></div>

Obtenez les éléments où commence la valeur

document.querySelectorAll('[href^="https://"]')

Le sélecteur pour "obtenir le premier élément" est correct mais pas cohérent avec les autres exemples - je pense qu'il manque "data-".
GuyPaddock

15

via la méthode Jquery filter ():

http://jsfiddle.net/9n4e1agn/1/

HTML:

<button   data-id='1'>One</button>
<button   data-id='2'>Two</button>

JavaScript:

$(function() {    
    $('button').filter(function(){
        return $(this).data("id")   == 2}).css({background:'red'});  
     });

Avez-vous essayé le violon? La méthode FIlter est juste une autre approche pour atteindre la même chose. Cela peut être utile lorsque vous disposez déjà d'un ensemble d'objets Jquery et que vous devez filtrer en fonction de l'attribut de données ou de toute autre chose.
Razan Paul

Mes excuses, @Blizzard. J'ai commenté la mauvaise réponse. Collé à droite maintenant. #AlwaysALongDayAtWork
Peter Bishop

15

La construction comme celle-ci: $('[data-XXX=111]')ne fonctionne pas dans Safari 8.0 .

Si vous les données ensemble d' attributs de cette façon: $('div').data('XXX', 111)il ne fonctionne que si vous les données directement dans l'attribut Entité DOM comme ceci: $('div').attr('data-XXX', 111).

Je pense que c'est parce que l'équipe jQuery a optimisé le garbage collector pour éviter les fuites de mémoire et les opérations lourdes sur la reconstruction DOM sur chaque attribut de données de changement.


Cela m'a beaucoup aidé - si j'utilisais les méthodes data ou prop, puis la sélection par $ ('... [data-x = "y"]') ne fonctionnait pas - j'ai utilisé attr à la place (cela pousse le changement d'attribut à DOM). Thx
Jarda

13

Pour que cela fonctionne dans Chrome, la valeur ne doit pas avoir une autre paire de guillemets.

Cela ne fonctionne, par exemple, que comme ceci:

$('a[data-customerID=22]');

4
Cela semble être incorrect. Au moins, ce n'est pas correct maintenant. Je viens d'utiliser $ ('[data-action = "setStatus"]'). RemoveClass ('disabled'); dans Chrome et cela fonctionne parfaitement.
Peter Bishop

Je suppose qu'il n'y a pas d'utilisation de "" à l'intérieur du sélecteur, il peut être utilisé comme$('[data-action=setStatus]').removeClass('disabled')
Animesh Singh

6

Il est parfois souhaitable de filtrer les éléments selon qu'ils ont des éléments de données qui leur sont attachés par programme (c'est-à-dire pas via les attributs dom):

$el.filter(function(i, x) { return $(x).data('foo-bar'); }).doSomething();

Ce qui précède fonctionne mais n'est pas très lisible. Une meilleure approche consiste à utiliser un pseudo-sélecteur pour tester ce genre de chose:

$.expr[":"].hasData = $.expr.createPseudo(function (arg) {
    return function (domEl) {
        var $el = $(domEl);
        return $el.is("[" + ((arg.startsWith("data-") ? "" : "data-") + arg) + "]") || typeof ($el.data(arg)) !== "undefined";
    };
});

Nous pouvons maintenant refactoriser la déclaration d'origine en quelque chose de plus fluide et lisible:

$el.filter(":hasData('foo-bar')").doSomething();

1
La première solution manque l'instruction return, elle doit être: $ el.filter (function (i, x) {return $ (x) .data ('foo-bar');}). DoSomething ();
Salma Gomaa

3

Juste pour compléter toutes les réponses avec certaines fonctionnalités du «standard de vie» - À l'heure actuelle (à l'ère html5), il est possible de le faire sans bibliothèque tierce:

  • JS pur / simple avec querySelector (utilise des sélecteurs CSS):
    • sélectionnez le premier dans DOM: document.querySelector('[data-answer="42"],[type="submit"]')
    • tout sélectionner dans DOM: document.querySelectorAll('[data-answer="42"],[type="submit"]')
  • CSS pur / simple
    • quelques balises spécifiques: [data-answer="42"],[type="submit"]
    • toutes les balises avec un attribut spécifique: [data-answer]ouinput[type]
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.