Muszę wybierać elementy na podstawie wartości przechowywanych w .data()
obiekcie elementu . Przynajmniej chciałbym wybrać właściwości danych najwyższego poziomu za pomocą selektorów, być może tak:
$('a').data("category","music");
$('a:data(category=music)');
A może selektor miałby zwykły format selektora atrybutów:
$('a[category=music]');
Lub w formacie atrybutu, ale ze specyfikatorem wskazującym, że jest w .data()
:
$('a[:category=music]');
Znalazłem realizację Jamesa Padolsey za patrzeć proste, ale dobra. Formaty selektora powyżej metod dublowania pokazane na tej stronie. Jest też ta łatka Sizzle .
Z jakiegoś powodu przypominam sobie, że jakiś czas temu jQuery 1.4 zawierałoby obsługę selektorów wartości w .data()
obiekcie jquery . Jednak teraz, gdy go szukam, nie mogę go znaleźć. Może widziałem tylko prośbę o dodanie funkcji. Czy jest na to wsparcie i po prostu tego nie widzę?
Idealnie, chciałbym wesprzeć właściwości podrzędne w data () za pomocą notacji kropkowej. Lubię to:
$('a').data("user",{name: {first:"Tom",last:"Smith"},username: "tomsmith"});
$('a[:user.name.first=Tom]');
Chciałbym również obsługiwać wiele selektorów danych, w których znajdują się tylko elementy ze WSZYSTKIM określonymi selektorami danych. Zwykły wielokrotny selektor jquery wykonuje operację LUB. Na przykład $('a.big, a.small')
wybiera a
tagi z klasą big
lub small
). Szukam AND, być może takiego:
$('a').data("artist",{id: 3281, name: "Madonna"});
$('a').data("category","music");
$('a[:category=music && :artist.name=Madonna]');
Wreszcie byłoby wspaniale, gdyby operatory porównania i funkcje wyrażenia regularnego były dostępne w selektorach danych. Tak $(a[:artist.id>5000])
byłoby możliwe. Zdaję sobie sprawę, że prawdopodobnie mógłbym wiele z tego zrobić filter()
, ale byłoby miło mieć prosty format selektora.
Jakie rozwiązania są dostępne, aby to zrobić? Czy Jame's Padolsey jest obecnie najlepszym rozwiązaniem? Moje obawy dotyczą przede wszystkim wydajności, ale także dodatkowych funkcji, takich jak notacja kropkowa pod-właściwości i wiele selektorów danych. Czy istnieją inne implementacje, które wspierają te rzeczy lub są w jakiś sposób lepsze?
źródło
Odpowiedzi:
Stworzyłem nowy
data
selektor, który powinien umożliwić wykonywanie zagnieżdżonych zapytań i warunki ORAZ. Stosowanie:Wzór jest następujący:
„operator” i „sprawdź” są opcjonalne. Tak więc, jeśli tylko
:data(a.b.c)
będzie to po prostu sprawdzić na truthiness dniaa.b.c
.Możesz zobaczyć dostępnych operatorów w kodzie poniżej. Jednym z nich jest
~=
testowanie wyrażeń regularnych:Przetestowałem to z kilkoma odmianami i wydaje się, że działa całkiem dobrze. Prawdopodobnie wkrótce dodam to jako repozytorium Github (z pełnym pakietem testowym), więc uważaj!
Kod:
źródło
$("a:data(condition),a:data(orCondition)")
... to będzie miało ten sam efekt. Im więcej funkcji dodasz, tym będzie wolniej. Jeśli logika jest złożona, użyj$(foo).filter(function(){...})
.jQuery.data
, który nie pobiera danych zdefiniowanych w atrybutach HTML5. Jeśli chcesz tę funkcjonalność, możesz zmienićjQuery.data
na$('selector').data
, ale to kompromis dla szybkości.W tej chwili wybieram tak:
Co wydaje się działać dobrze, ale byłoby miło, gdyby jQuery mógł wybrać ten atrybut bez prefiksu „data-”.
Nie testowałem tego z danymi dodawanymi dynamicznie do elementów za pomocą jQuery, więc może to być wadą tej metody.
źródło
Możesz także użyć prostej funkcji filtrowania bez żadnych wtyczek. Nie jest to dokładnie to, czego chcesz, ale wynik jest taki sam:
źródło
filter
funkcja przejścia może zaakceptować funkcję testową =) dziękiChcę cię ostrzec
$('a[data-attribute=true]')
to nie działa, zgodnie z odpowiedzią Ashleya, jeśli dołączyłeś dane do elementu DOM za pomocą funkcji data ().Działa tak, jak można się spodziewać, jeśli dodasz rzeczywistą wartość danych do kodu HTML, ale jQuery przechowuje dane w pamięci, więc wyniki, które uzyskasz
$('a[data-attribute=true]')
, nie byłyby prawidłowe.Musisz użyć wtyczki danych http://code.google.com/p/jquerypluginsblog/ , skorzystać z
filter
rozwiązania Dmitrigo lub wykonać $ .each dla wszystkich elementów i sprawdzić iteracyjnie .data ()źródło
Jest
:data()
wtyczka filtra , która właśnie to robi :)Kilka przykładów opartych na twoim pytaniu:
Wydajność nie będzie wyjątkowo świetna w porównaniu z tym, co jest możliwe , wybieranie
$._cache
i chwytanie odpowiednich elementów jest zdecydowanie najszybsze, ale o wiele bardziej okrągłe i niezbyt „jQuery-ey” pod względem sposobu dotarcia do rzeczy (zazwyczaj przychodzisz od strony elementu). Co do mojej głowy, nie jestem pewien, czy i tak jest to najszybsze, ponieważ proces przechodzenia od unikalnego identyfikatora do elementu jest sam w sobie skomplikowany pod względem wydajności.Wspomniany selektor porównania najlepiej będzie zrobić w
.filter()
, nie ma wbudowanej obsługi tego we wtyczce, chociaż można go dodać bez większych problemów.źródło
data-*
atrybutów HTML5 i wybranie ich byłoby szybsze niż wybranie.data()
właściwości? A także jakiś pomysł, gdzie mogę dowiedzieć się więcej o cache $ ._? Poszukałem go, ale niewiele znajduję.$.cache
nie jest$._cache
, tutaj możesz zobaczyć, jak jest zaimplementowany i używany w jądrze jQuery: github.com/jquery/jquery/blob/master/src/data.js#L4 Kiedy.data()
go wywołujesz , przechowuje go jako obiekt in$.cache[elementUniqueID]
, który jest Id przypisany w razie potrzeby w sposób niekorzystny każdemu elementowi, np. 1, 2, 3 itd. Ten identyfikator wspinania zostanie ujawniony w jQuery 1.4.3. Myślę, że na podstawie komentarzy git z innego dnia. Zakładam, że trasa HTML 5 byłaby szybsza, zależy od dostępnych optymalizacji przeglądarki (jestem pewien, że więcej będzie dostępnych).Możesz ustawić
data-*
atrybut wiązu za pomocąattr()
, a następnie wybrać za pomocą tego atrybutu:a teraz tym wiąz, zarówno
attr()
idata()
przyniesie 123 :Jeśli jednak zmienisz wartość na 456 za pomocą
attr()
,data()
nadal będzie 123 :Tak jak ja to rozumiem, wydaje się, że prawdopodobnie powinien omijać przenikanie
attr()
idata()
poleceń w kodzie, jeśli nie muszę. Ponieważattr()
wydaje się, że odpowiada bezpośrednio DOM, podczas gdydata()
współdziała z „pamięcią”, chociaż jego początkowa wartość może pochodzić z DOM. Ale kluczową kwestią jest to, że te dwie niekoniecznie są zsynchronizowane.Więc bądź ostrożny.
W każdym razie, jeśli nie zmienisz
data-*
atrybutu w DOM lub w pamięci, nie będziesz miał problemu. Gdy tylko zaczniesz modyfikować wartości, mogą pojawić się potencjalne problemy.Dzięki @Clarence Liu do odpowiedzi @ Ash, a także tego postu .
źródło
To działa. Zobacz Selektor atrybutów równych [nazwa = ”wartość”] .
źródło
Jeśli używasz również jQueryUI, otrzymujesz (prostą) wersję
:data
selektora, która sprawdza obecność elementu danych, dzięki czemu możesz zrobić coś takiego$("div:data(view)")
, lub$( this ).closest(":data(view)")
.Zobacz http://api.jqueryui.com/data-selector/ . Nie wiem, jak długo to trwały, ale już jest!
źródło
Oto wtyczka, która upraszcza życie https://github.com/rootical/jQueryDataSelector
Użyj tego w ten sposób:
źródło