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.

Hazem Salama
la source
2
Voir aussi stackoverflow.com/q/4191386/292060
goodeye
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')).

Mathias Bynens
la source
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>
JTG
la source
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"]');
drzaus
la source
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
78

Je n'ai pas vu de réponse JavaScript sans jQuery. J'espère que cela aide quelqu'un.

var elements = document.querySelectorAll('[data-customerID="22"]');

elements[0].innerHTML = 'it worked!';
<a data-customerID='22'>test</a>

Info:

Sjoerd Pottuit
la source
1
Merci pour cela. Agréable de voir des solutions non jquery.
Chuck
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"]');
Travis J
la source
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://"]')
étoxine
la source
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'});  
     });
Razan Paul
la source
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.

Anton Danilchenko
la source
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]');
user55318
la source
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();
XDS
la source
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]
Sven
la source