jQuery jak znaleźć element na podstawie wartości atrybutu danych?


994

Mam następujący scenariusz:

var el = 'li';

a na stronie znajduje się 5 <li>z data-slide=numberatrybutem (odpowiednio 1,2,3,4,5) .

Teraz muszę znaleźć numer aktywnego slajdu, który jest mapowany var current = $('ul').data(current);i aktualizowany przy każdej zmianie slajdu.

Do tej pory moje próby zakończyły się niepowodzeniem, próbując skonstruować selektor pasujący do bieżącego slajdu:

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

nic nie pasuje / nie zwraca…

Powodem, dla którego nie mogę na stałe zakodować liczęści, jest to, że jest to zmienna dostępna dla użytkownika, którą w razie potrzeby można zmienić na inny element, więc nie zawsze może to być li.

Jakieś pomysły na to, czego mi brakuje?


6
na pewno w swoim .find(el+[data-slide=+current+]);kodzie jest kod, który piszesz? wygląda na to, że przegapiłeś kilka cytatów z"[data-slide]"
Xandy

To pomogło mi wybrać wszystkie atrybuty danych (niezależnie od wartości): $('*[data-slide]')Możesz go używać np. Z$('*[data-slide]').each( function() { ... });
Kai Noack

Odpowiedzi:


1481

Musisz wprowadzić wartość currentdo selektora Attribute Equals :

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

W przypadku starszych środowisk JavaScript ( ES5 i wcześniejszych):

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

8
@Jannis, możesz to zrobić $("ul").find(el + "[data-slide='" + current +"']");.
Frédéric Hamidi

7
@ c00lryguy, interfejs użytkownika jQuery definiuje jeden, a wokół istnieją autonomiczne implementacje . Wygląda na to, że próby dodania go do jQuery Core zostały odrzucone . Dwukrotnie .
Frédéric Hamidi

6
ta odpowiedź na podobny post ma przykład funkcji filtrowania
drzaus

77
Obawiam się, że to nie zadziała, jeśli dane zostaną dodane za pomocą funkcji jQuery .data (...), ponieważ nie zawsze renderuje to atrybut i czasami używa mechanizmu przechowywania specyficznego dla przeglądarki. Kolejny powód, dla którego chciałbym, aby rdzeń jQuery miał selektor specyficzny dla danych.
AaronLS

77
Zauważ, że to nie działa dla elementów, w których ustawiasz dane za pomocą $ ('# element'). Data ('some-att-name', value); ale tylko dla osób z zakodowanym atrybutem. Mam ten problem i aby działał, ustaw dane, pisząc atrybut bezpośrednio $ ('# element'). Attr ('data-some-att-name', wartość);
Paweł

463

w przypadku, gdy nie chcesz wpisywać tego wszystkiego, oto krótszy sposób na zapytanie według atrybutu danych:

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

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


31
Dla tych, którym zależy, ze względu na strukturę <ul><li data-slide="item"></li></ul>selektor odpowiedzi zwróci niezdefiniowany, więc nie będzie działał, biorąc pod uwagę scenariusz użytkownika. Ta odpowiedź DZIAŁA dla struktury <ul data-slide="item"><li></li></ul> Chociaż rozumiem, dlaczego jest popularna ze względu na zwięzłość, jest to technicznie nieprawidłowa odpowiedź. jsfiddle.net/py5p2abL/1
akousmata

4
Nie zapomnij potraktować tego jako tablicy. Użyj, [0]aby uzyskać dostęp do pierwszego znalezionego elementu.
Aminah Nuraini

Dziwny efekt uboczny ... ta metoda działała, dopasowując element do atrybutu danych, gdy .find("[data-attrib='value']")nie działał. Nie wiem, czy wartości to atrybuty danych zostały dodane przez jQuery czy nie ...
błąd

1
To nie jest dziwne, ponieważ dwie odpowiedzi robią 2 różne rzeczy. $.findkonkretnie znajduje potomków tego elementu, ale użycie składni filtru w ciągu selektora po prostu odfiltruje wyniki.
Phil

227

Podczas wyszukiwania za pomocą [data-x = ...] uważaj, nie działa z seter 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

Możesz użyć tego zamiast:

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

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

1
$.fn.filterByDatajest znakomity; jest to jednak ostrzeżenie dla kopiujących-pasterów tam ... musisz tylko $('<b>').filterByData('x', 1)znaleźć <b>tagi data-x="1". jeśli skopiujesz i wkleisz .data(x, 1)część ... data-xprzed filtrowaniem ustawisz wartość „1”.
WEBjuju

39

Poprawiłem rozszerzenie filterByData od psycho brm do jQuery.

Tam, gdzie poprzednie rozszerzenie szukało pary klucz-wartość, za pomocą tego rozszerzenia można dodatkowo wyszukiwać obecność atrybutu danych, niezależnie od jego wartości.

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

Stosowanie:

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

Lub skrzypce: http://jsfiddle.net/PTqmE/46/


34

Bez JQuery, ES6

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

Wiem, że pytanie dotyczy JQuery, ale czytelnicy mogą chcieć czystej metody JS.


33

Napotkałem ten sam problem podczas pobierania elementów za pomocą jQuery i atrybutu data- *.

więc w celach informacyjnych najkrótszy kod znajduje się tutaj:

To jest mój kod HTML:

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

To jest mój selektor jQuery:

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


15

Ten selektor $("ul [data-slide='" + current +"']");będzie działał dla następującej struktury:

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

Chociaż $("ul[data-slide='" + current +"']");będzie to działać dla:

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


12

Wracając do pierwotnego pytania o to, jak to zrobić, nie znając z góry typu elementu, wykonuje następujące czynności:

$(ContainerNode).find(el.nodeName + "[data-slide='" + current + "']");
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.