Selettore jQuery o?


325

Mi chiedo se c'è un modo per avere la logica "OR" nei selettori jQuery. Ad esempio, so che un elemento è un discendente di un elemento con classe classA o classB e voglio fare qualcosa del genere elem.parents('.classA or .classB'). JQuery fornisce tale funzionalità?

Risposte:


494

Usa una virgola.

'.classA, .classB'

Puoi scegliere di omettere lo spazio.


43
Va notato che questo non è in realtà un 'o' selettore, più come più selettori in uno.
alex,

49
@alex: ma non selezionerà lo stesso elemento due volte (cosa che farebbe un operatore di concatenazione). È davvero un selettore OR perché crea un'UNIONE di due o più insiemi (mentre AND è un'intersezione).
cletus,

Grazie, funziona. A causa di una supervisione del debug ho pensato che l'uso di una virgola significa 'AND'.
Suan

38
ANDsarebbe .classA.classB.
Daniel A. White,

2
In realtà dipende da cosa implicava la domanda originale ... vale a dire: in genere un operatore "o" andrà in corto circuito. Quindi un 'o' operatore nel linguaggio jquery, potrebbe anche cortocircuitare.
Mathew,

71

L'uso di una virgola potrebbe non essere sufficiente se si hanno più oggetti jQuery che devono essere uniti.

Il metodo .add () aggiunge gli elementi selezionati al set di risultati:

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

È più dettagliato di '.classA, .classB', ma consente di creare selettori più complessi come il seguente:

// (classA which has <p> descendant) OR (<div> ancestors of classB)
jQuery('.classA').has('p').add(jQuery('.classB').parents('div'));

22

Ho scritto un plugin incredibilmente semplice (5 righe di codice) proprio per questa funzionalità:

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

Ti permette di dire efficacemente "ottieni questo elemento, o se quell'elemento non esiste, usa questo elemento". Per esempio:

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

Mentre la risposta accettata fornisce funzionalità simili a questa, se esistono entrambi i selettori (prima e dopo la virgola), entrambi i selettori verranno restituiti.

Spero che si riveli utile a chiunque possa atterrare su questa pagina tramite Google.


4
Non è così che funziona l'operatore booleano OR. Se entrambi i selettori restituiscono elementi, l'operatore OR deve restituire tutti e non solo gli elementi del primo selettore. Il tuo plugin dovrebbe essere chiamato "ifEmpty" o "else" o qualcosa del genere.
Alp

13
@Alp: considera il comportamento di "a" || "b"vs. null || "b"in vaniglia JS. Se applichiamo lo stesso comportamento qui, $(a).or(b)dovrebbe tornare $(a)se esiste, altrimenti dovrebbe tornare $(b). Non credo che ci sia nulla di sbagliato in questa nomenclatura, in quanto "o" corrisponde al comportamento di JS "||" (o) operatore.
FtDRbwLXw6,

4
Lo vedo anche come un or. Quello di cui stanno parlando gli altri è più simile a un'azione concato merge.
Léon Pelletier,

1
Personalmente non lo definirei "o", poiché potrebbe creare confusione (anche se tecnicamente potrebbe essere corretto in quanto è un tipo speciale di if / o). Questa è effettivamente una coalescenza nulla, che si chiama cose diverse e hanno operatori diversi in lingue diverse: en.wikipedia.org/wiki/Null_coalescing_operator
JanErikGunnar,

Il termine 'xor' (esclusivo o) sarebbe il termine esatto, ma spesso le persone cercano o cercano xor, poiché xor è generalmente, in termini comuni, un tipo specifico di 'o'.
liljoshu,

17

Se stai cercando di usare il costrutto standard di element = element1 || element2 dove JavaScript restituirà il primo che è vero, potresti fare esattamente questo:

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

che restituirebbe il primo elemento effettivamente trovato. Ma un modo migliore sarebbe probabilmente usare il costrutto virgola del selettore jQuery (che restituisce una matrice di elementi trovati) in questo modo:

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

che restituirà il primo elemento trovato.

Di tanto in tanto lo trovo per trovare un elemento attivo in un elenco o un elemento predefinito se non è presente alcun elemento attivo. Per esempio:

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

che restituirà qualsiasi li con una classe di attivo o, se non ce ne sono, restituirà solo l'ultimo li.

O funzionerà. Ci sono potenziali penalità di prestazione, tuttavia, come il || interromperà l'elaborazione non appena troverà qualcosa di vero mentre l'approccio array proverà a trovare tutti gli elementi anche se ne ha già trovato uno. Poi di nuovo, usando il || il costrutto potrebbe potenzialmente avere problemi di prestazioni se deve passare attraverso diversi selettori prima di trovare quello che restituirà, perché deve chiamare l'oggetto jQuery principale per ognuno (non so davvero se questo è un hit delle prestazioni o no, sembra logico che potrebbe essere). In generale, tuttavia, utilizzo l'approccio array quando il selettore è una stringa piuttosto lunga.


Penso che find ('. SomethingToBeFound, .somethingElseToBeFound') non sia uguale a || costruire. Perché trova se .somethingElseToBeFound è in DOM prima di .somethingToBeFound, verrebbe restituito anche se esiste .somethingToBeFound.
rimuovere il

0

Finalmente ho trovato l'hack come fare:

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

(seleziona div con classe classAOR classBcon span figlio diretto)


-2

Daniel A. White Solution funziona alla grande per le lezioni.

Ho una situazione in cui ho dovuto trovare campi di input come donee_1_card dove 1 è un indice.

La mia soluzione è stata

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

Anche se non sono sicuro di quanto sia ottimale.

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.