jQuery comment trouver un élément basé sur une valeur d'attribut de données?

994

J'ai le scénario suivant:

var el = 'li';

et il y a 5 <li>sur la page chacun avec un data-slide=numberattribut (le nombre étant 1,2,3,4,5 respectivement) .

Je dois maintenant trouver le numéro de diapositive actuellement actif qui est mappé var current = $('ul').data(current);et mis à jour à chaque changement de diapositive.

Jusqu'à présent, mes essais ont échoué, essayant de construire le sélecteur qui correspondrait à la diapositive actuelle:

$('ul').find(el+[data-slide=+current+]);

ne correspond / ne renvoie rien…

La raison pour laquelle je ne peux pas coder en dur la lipartie est qu'il s'agit d'une variable accessible à l'utilisateur qui peut être changée en un élément différent si nécessaire, donc ce n'est pas toujours un li.

Des idées sur ce qui me manque?

Jannis
la source
6
vous êtes sûr que dans votre .find(el+[data-slide=+current+]);est le code que vous écrivez? il semble que vous avez manqué quelques citations à"[data-slide]"
xandy
C'est ce qui m'a aidé à sélectionner tous les attributs de données (quelle que soit la valeur): $('*[data-slide]')vous pouvez l'utiliser avec par exemple$('*[data-slide]').each( function() { ... });
Kai Noack

Réponses:

1481

Vous devez injecter la valeur de currentdans un sélecteur d' égalité d'attribut :

$("ul").find(`[data-slide='${current}']`)

Pour les environnements JavaScript plus anciens ( ES5 et versions antérieures):

$("ul").find("[data-slide='" + current + "']"); 
Frédéric Hamidi
la source
8
@Jannis, tu pourrais le faire $("ul").find(el + "[data-slide='" + current +"']");.
Frédéric Hamidi
7
@ c00lryguy, l' interface utilisateur jQuery en définit une, et il existe des implémentations autonomes . Il semble que les tentatives pour l'ajouter à jQuery Core aient été rejetées . Deux fois .
Frédéric Hamidi
6
cette réponse sur un post similaire a un exemple de la fonction de filtre
drzaus
77
Je crains que cela ne fonctionne pas si des données ont été ajoutées via la fonction jQuery .data (...), car cela ne rend pas toujours un attribut et utilise donc un mécanisme de stockage spécifique au navigateur. Une autre raison pour laquelle je souhaite que jQuery core ait un sélecteur spécifique aux données.
AaronLS
77
Notez que cela ne fonctionne pas pour les éléments où vous définissez des données avec $ ('# element'). Data ('some-att-name', value); mais uniquement pour ceux avec un attribut codé en dur. J'ai ce problème et pour le faire fonctionner, définissez les données en écrivant directement l'attribut $ ('# element'). Attr ('data-some-att-name', value);
Pawel
463

au cas où vous ne voudriez pas taper tout cela, voici un moyen plus court de rechercher par attribut de données:

$("ul[data-slide='" + current +"']");

Pour info: http://james.padolsey.com/javascript/a-better-data-selector-for-jquery/

KevinDeus
la source
31
Pour ceux d'entre vous qui s'en soucient, compte tenu de la structure, <ul><li data-slide="item"></li></ul>le sélecteur de cette réponse retournera indéfini de sorte qu'il ne fonctionne pas compte tenu du scénario de l'utilisateur. Cette réponse fonctionnera pour la structure <ul data-slide="item"><li></li></ul> Bien que je comprenne pourquoi sa popularité en raison de sa brièveté, c'est techniquement une réponse incorrecte. jsfiddle.net/py5p2abL/1
akousmata
4
N'oubliez pas de le traiter comme un tableau. Utilisez [0]pour accéder au premier élément trouvé.
Aminah Nuraini
Un effet secondaire bizarre ... cette méthode a fonctionné en faisant correspondre l'élément avec l'attribut data lorsque cela .find("[data-attrib='value']")n'a pas fonctionné. Je ne sais pas si les valeurs étaient des attributs de données qui ont été ajoutés par jQuery ou non ...
erreur
1
Ce n'est pas bizarre car les deux réponses font 2 choses différentes. trouve$.find spécifiquement les descendants de cet élément, mais l'utilisation de la syntaxe de filtre dans la chaîne de sélection filtrera simplement les résultats.
Phil
227

Lors de la recherche avec [data-x = ...], attention, cela ne fonctionne pas avec le setter jQuery.data (..) :

$('<b data-x="1">'  ).is('[data-x=1]') // this works
> true

$('<b>').data('x', 1).is('[data-x=1]') // this doesn't
> false

$('<b>').attr('data-x', 1).is('[data-x=1]') // this is the workaround
> true

Vous pouvez utiliser ceci à la place:

$.fn.filterByData = function(prop, val) {
    return this.filter(
        function() { return $(this).data(prop)==val; }
    );
}

$('<b>').data('x', 1).filterByData('x', 1).length
> 1
psycho brm
la source
1
le $.fn.filterByDataest brillant; cependant, c'est un avertissement pour les copieurs là-bas ... il vous suffit $('<b>').filterByData('x', 1)de trouver des <b>balises avec data-x="1". si vous copiez-collez la .data(x, 1)portion ... vous mettrez votre data-x"1" avant de filtrer.
WEBjuju
39

J'ai amélioré l'extension filterByData de psycho brm à jQuery.

Lorsque l'ancienne extension recherchait une paire clé-valeur, cette extension vous permet en outre de rechercher la présence d'un attribut de données, quelle que soit sa valeur.

(function ($) {

    $.fn.filterByData = function (prop, val) {
        var $self = this;
        if (typeof val === 'undefined') {
            return $self.filter(
                function () { return typeof $(this).data(prop) !== 'undefined'; }
            );
        }
        return $self.filter(
            function () { return $(this).data(prop) == val; }
        );
    };

})(window.jQuery);

Usage:

$('<b>').data('x', 1).filterByData('x', 1).length    // output: 1
$('<b>').data('x', 1).filterByData('x').length       // output: 1

Ou le violon: http://jsfiddle.net/PTqmE/46/

bPratik
la source
34

Sans JQuery, ES6

document.querySelectorAll(`[data-slide='${current}']`);

Je sais que la question concerne JQuery, mais les lecteurs voudront peut-être une méthode JS pure.

rap-2-h
la source
33

J'ai rencontré le même problème lors de la récupération d'éléments à l'aide de jQuery et de l'attribut data- *.

donc pour votre référence le code le plus court est ici:

Voici mon code HTML:

<section data-js="carousel"></section>
<section></section>
<section></section>
<section data-js="carousel"></section>

Voici mon sélecteur jQuery:

$('section[data-js="carousel"]');
// this will return array of the section elements which has data-js="carousel" attribute.
user1378423
la source
19
$("ul").find("li[data-slide='" + current + "']");

J'espère que cela fonctionnera mieux

Merci

Jomin George Paul
la source
15

Ce sélecteur $("ul [data-slide='" + current +"']");fonctionnera pour la structure suivante:

<ul><li data-slide="item"></li></ul>  

Bien que cela $("ul[data-slide='" + current +"']");fonctionne pour:

<ul data-slide="item"><li></li></ul>

Matas Vaitkevicius
la source
12

Pour revenir à sa question initiale, sur la façon de faire fonctionner cela sans connaître à l'avance le type d'élément, voici ce qui suit:

$(ContainerNode).find(el.nodeName + "[data-slide='" + current + "']");
Bryan Garaventa
la source