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.