jQuery OR Selector?

325

Zastanawiam się, czy istnieje sposób na logikę „LUB” w selektorach jQuery. Na przykład wiem, że element jest potomkiem elementu z klasą classA lub classB i chcę zrobić coś takiego elem.parents('.classA or .classB'). Czy jQuery zapewnia taką funkcjonalność?

Suan
źródło

Odpowiedzi:

494

Użyj przecinka.

'.classA, .classB'

Możesz pominąć spację.

Daniel A. White
źródło
43
Należy zauważyć, że tak naprawdę nie jest to selektor „lub”, a bardziej jak wiele selektorów w jednym.
alex
49
@alex: ale nie wybierze dwukrotnie tego samego elementu (co zrobiłby operator konkatenacji). To naprawdę jest selektor OR, ponieważ tworzy UNION dwóch lub więcej zbiorów (podczas gdy AND jest przecięciem).
cletus
Dzięki, to działa. Z powodu niedopatrzenia dotyczącego debugowania pomyślałem, że użycie przecinka oznacza „ORAZ”.
Suan
38
ANDbyłoby .classA.classB.
Daniel A. White
2
W rzeczywistości zależy to od tego, co sugerowało pierwotne pytanie ... tj. Klasycznie „lub” operator spowoduje zwarcie. Zatem operator „lub” w języku jquery mógłby również spowodować zwarcie.
Mathew
71

Używanie przecinka może nie być wystarczające, jeśli masz wiele obiektów jQuery, które muszą zostać połączone.

Metoda .add () dodaje wybrane elementy do zestawu wyników:

// classA OR classB
jQuery('.classA').add('.classB');

Jest bardziej szczegółowy '.classA, .classB', ale pozwala budować bardziej złożone selektory, takie jak:

// (classA which has <p> descendant) OR (<div> ancestors of classB)
jQuery('.classA').has('p').add(jQuery('.classB').parents('div'));
Turnia
źródło
22

Napisałem niesamowicie prostą (5 linii kodu) wtyczkę do tej właśnie funkcji:

http://byrichardpowell.github.com/jquery-or/

Pozwala skutecznie powiedzieć „pobierz ten element lub jeśli ten element nie istnieje, użyj tego elementu”. Na przykład:

$( '#doesntExist' ).or( '#exists' );

Chociaż zaakceptowana odpowiedź zapewnia podobną funkcjonalność, jeśli istnieją oba selektory (przed i po przecinku), oba selektory zostaną zwrócone.

Mam nadzieję, że okaże się pomocny dla każdego, kto może wylądować na tej stronie za pośrednictwem Google.

Richard Powell
źródło
4
Nie tak działa operator logiczny OR. Jeśli oba selektory zwracają elementy, operator OR powinien zwrócić wszystkie, a nie tylko elementy pierwszego selektora. Twoja wtyczka powinna mieć nazwę „ifEmpty” lub „else” albo coś w tym rodzaju.
Alp
13
@Alp: Zastanów się nad zachowaniem "a" || "b"vs. null || "b"w waniliowym JS. Jeśli zastosujemy to samo zachowanie tutaj, $(a).or(b)powinien zwrócić, $(a)jeśli istnieje, w przeciwnym razie powinien wrócić $(b). Nie sądzę, żeby było coś złego w tej nomenklaturze, ponieważ „lub” pasuje do zachowania JS „||” (lub) operator.
FtDRbwLXw6 18.10.13
4
Widzę to również jako or. To, o czym mówią inni, przypomina bardziej akcję concatlub mergeakcję.
Léon Pelletier
1
Osobiście nie nazwałbym tego „lub”, ponieważ może to prowadzić do zamieszania (nawet jeśli technicznie może to być poprawne, ponieważ jest to szczególny rodzaj „/”). Jest to faktycznie zerowa koalescencja, która nazywa się różnymi rzeczami i ma różne operatory w różnych językach: en.wikipedia.org/wiki/Null_coalescing_operator
JanErikGunnar
Termin „xor” (wyłączny lub) byłby dokładnym terminem, ale często ludzie szukają lub szukają xor, ponieważ xor jest, ogólnie rzecz biorąc, specyficznym typem „lub”.
liljoshu
17

Jeśli chcesz użyć standardowej konstrukcji elementu = element1 || element2, w którym JavaScript zwróci pierwszy, który jest prawdziwy, możesz zrobić dokładnie to:

element = $('#someParentElement .somethingToBeFound') || $('#someParentElement .somethingElseToBeFound');

co zwróciłoby pierwszy znaleziony element. Ale lepszym sposobem byłoby prawdopodobnie użycie konstrukcji przecinka selektora jQuery (która zwraca tablicę znalezionych elementów) w następujący sposób:

element = $('#someParentElement').find('.somethingToBeFound, .somethingElseToBeFound')[0];

który zwróci pierwszy znaleziony element.

Używam tego od czasu do czasu, aby znaleźć element aktywny na liście lub jakiś element domyślny, jeśli nie ma elementu aktywnego. Na przykład:

element = $('ul#someList').find('li.active, li:first')[0] 

który zwróci dowolne li z klasą aktywnych lub, jeśli nie będzie, po prostu zwróci ostatnie li.

Albo zadziała. Istnieją jednak potencjalne kary za wyniki, ponieważ || przestanie przetwarzać, gdy tylko znajdzie coś prawdziwego, podczas gdy podejście tablicowe spróbuje znaleźć wszystkie elementy, nawet jeśli już je znalazł. Z drugiej strony, używając || konstrukcja może potencjalnie mieć problemy z wydajnością, jeśli będzie musiała przejść przez kilka selektorów przed znalezieniem tego, który zwróci, ponieważ musi wywołać główny obiekt jQuery dla każdego (naprawdę nie wiem, czy jest to wzrost wydajności, czy nie, wydaje się to logiczne, że tak może być). Ogólnie jednak używam podejścia tablicowego, gdy selektor jest raczej długim ciągiem.

Ken Dickinson
źródło
Myślę, że find ('. SomethingToBeFound, .somethingElseToBeFound') nie jest tym samym co || skonstruować. Ponieważ sprawdź, czy .somethingElseToBeFound znajduje się w DOM przed .somethingToBeFound, zostałby zwrócony, nawet jeśli istnieje .somethingToBeFound.
remo
0

Wreszcie znalazłem hacka, jak to zrobić:

div:not(:not(.classA,.classB)) > span

(wybiera div z klasą classAOR classBz bezpośrednim rozpiętością potomną)

midlan
źródło
-2

Daniel A. White Solution świetnie sprawdza się na zajęciach.

Mam sytuację, w której musiałem znaleźć pola wejściowe, takie jak donee_1_card, gdzie 1 to indeks.

Moje rozwiązanie zostało

$("input[name^='donee']" && "input[name*='card']")

Chociaż nie jestem pewien, jak optymalne jest.

FDussault
źródło