jQuery come trovare un elemento basato su un valore di attributo di dati?


994

Ho il seguente scenario:

var el = 'li';

e ci sono 5 <li>sulla pagina ciascuno con un data-slide=numberattributo (il numero è rispettivamente 1,2,3,4,5) .

Ora ho bisogno di trovare il numero di diapositiva attualmente attivo che è mappato var current = $('ul').data(current);e viene aggiornato ad ogni cambio di diapositiva.

Finora i miei tentativi non hanno avuto successo, cercando di costruire il selettore che corrisponderebbe alla diapositiva corrente:

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

non corrisponde / non restituisce nulla ...

Il motivo per cui non riesco a codificare la liparte è che questa è una variabile accessibile dall'utente che può essere cambiata in un elemento diverso, se necessario, quindi potrebbe non essere sempre una li.

Qualche idea su cosa mi sto perdendo?


6
sei sicuro nel tuo .find(el+[data-slide=+current+]);codice di scrittura? sembra che tu abbia perso alcune citazioni a"[data-slide]"
xandy il

Questo è ciò che mi ha aiutato a selezionare tutti gli attributi dei dati (indipendentemente dal valore): $('*[data-slide]')puoi usarli con ad es.$('*[data-slide]').each( function() { ... });
Kai Noack

Risposte:


1481

Devi currentinserire il valore di in un selettore Attributo uguale :

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

Per ambienti JavaScript meno recenti ( ES5 e precedenti):

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

8
@Jannis, potresti farlo $("ul").find(el + "[data-slide='" + current +"']");.
Frédéric Hamidi,

7
@ c00lryguy, l' interfaccia utente jQuery ne definisce una e ci sono implementazioni standalone in giro. Sembra che i tentativi di averlo aggiunto a jQuery Core siano stati respinti . Due volte .
Frédéric Hamidi

6
questa risposta su un post simile ha un esempio della funzione filtro
drzaus

77
Temo che questo non funzionerà se i dati sono stati aggiunti tramite la funzione jQuery .data (...), dal momento che questo non rende sempre un attributo e che a volte utilizza un meccanismo di archiviazione specifico del browser. Un altro motivo per cui vorrei che jQuery core avesse un selettore specifico per i dati.
AaronLS

77
Si noti che non funziona per gli elementi in cui si impostano i dati con $ ('# element'). Data ('some-att-name', value); ma solo per quelli con attributo hardcoded. Ho questo problema e per farlo funzionare imposta i dati scrivendo l'attributo direttamente $ ('# element'). Attr ('data-some-att-name', value);
Pawel,

463

nel caso in cui non si desideri digitare tutto ciò, ecco un modo più breve per eseguire una query per attributo di dati:

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

Cordiali saluti: http://james.padolsey.com/javascript/a-better-data-selector-for-jquery/


31
Per quelli a cui tenete, data la struttura <ul><li data-slide="item"></li></ul>il selettore di questa risposta restituirà un valore indefinito, quindi non funziona in base allo scenario dell'utente. Questa risposta funzionerà per la struttura <ul data-slide="item"><li></li></ul> Mentre capisco perché la sua popolarità a causa della brevità, è tecnicamente una risposta errata. jsfiddle.net/py5p2abL/1
akousmata il

4
Non dimenticare di trattarlo come un array. Utilizzare [0]per accedere al primo elemento trovato.
Aminah Nuraini,

Un bizzarro effetto collaterale ... questo metodo ha funzionato abbinando l'elemento all'attributo data quando .find("[data-attrib='value']")non ha funzionato. Non so se i valori fossero attributi di dati aggiunti da jQuery o no ...
errore

1
Non è strano perché le due risposte fanno 2 cose diverse. trova in modo$.find specifico i discendenti di quell'elemento, ma l'uso della sintassi del filtro nella stringa del selettore filtra semplicemente i risultati.
Phil,

227

Durante la ricerca con [data-x = ...], attenzione, non funziona con il 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

È possibile utilizzare questo invece:

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

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

1
l' $.fn.filterByDataè brillante; tuttavia, questo è un avvertimento per i copia-paster là fuori ... devi solo $('<b>').filterByData('x', 1)trovare i <b>tag con data-x="1". se copi e incolli la .data(x, 1)parte ... imposterai il tuo data-x"1" prima di filtrare.
WEBjuju

39

Ho migliorato l'estensione filterByData di psycho brm a jQuery.

Laddove la precedente estensione ha cercato su una coppia chiave-valore, con questa estensione è inoltre possibile cercare la presenza di un attributo dati, indipendentemente dal suo valore.

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

Uso:

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

O il violino: http://jsfiddle.net/PTqmE/46/


34

Senza JQuery, ES6

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

So che la domanda riguarda JQuery, ma i lettori potrebbero desiderare un metodo JS puro.


33

Ho riscontrato lo stesso problema durante il recupero degli elementi utilizzando l'attributo jQuery e data- *.

quindi per tuo riferimento il codice più breve è qui:

Questo è il mio codice HTML:

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

Questo è il mio selettore jQuery:

$('section[data-js="carousel"]');
// this will return array of the section elements which has data-js="carousel" attribute.

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

Spero che possa funzionare meglio

Grazie


15

Questo selettore $("ul [data-slide='" + current +"']");funzionerà per la seguente struttura:

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

Mentre questo $("ul[data-slide='" + current +"']");funzionerà per:

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


12

Tornando alla sua domanda originale, su come farlo funzionare senza conoscere in anticipo il tipo di elemento, il seguente fa:

$(ContainerNode).find(el.nodeName + "[data-slide='" + current + "']");
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.