jQuery ODER Selektor?

325

Ich frage mich, ob es eine Möglichkeit gibt, "ODER" -Logik in jQuery-Selektoren zu haben. Ich weiß zum Beispiel, dass ein Element entweder ein Nachkomme eines Elements mit der Klasse classA oder classB ist, und ich möchte so etwas tun elem.parents('.classA or .classB'). Bietet jQuery solche Funktionen?

Suan
quelle

Antworten:

494

Verwenden Sie ein Komma.

'.classA, .classB'

Sie können das Leerzeichen weglassen.

Daniel A. White
quelle
43
Es sollte beachtet werden, dass dies nicht wirklich ein 'oder' Selektor ist, eher wie mehrere Selektoren in einem.
alex
48
@alex: Es wird jedoch nicht zweimal dasselbe Element ausgewählt (was ein Verkettungsoperator tun würde). Es ist wirklich ein ODER-Selektor, weil es eine UNION aus zwei oder mehr Mengen erstellt (während UND eine Schnittmenge ist).
Cletus
Danke, das funktioniert. Aufgrund eines Debugging-Versehens dachte ich, dass die Verwendung eines Kommas 'UND' bedeutet.
Suan
38
ANDwäre .classA.classB.
Daniel A. White
2
Es hängt tatsächlich davon ab, was die ursprüngliche Frage implizierte ... dh: Klassischerweise wird ein 'oder' Operator kurzschließen. Somit könnte ein 'oder' Operator in der Abfrage möglicherweise auch kurzschließen.
Mathew
71

Die Verwendung eines Kommas ist möglicherweise nicht ausreichend, wenn Sie mehrere jQuery-Objekte haben, die verbunden werden müssen.

Die Methode .add () fügt die ausgewählten Elemente zur Ergebnismenge hinzu:

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

Es ist ausführlicher als '.classA, .classB', aber Sie können komplexere Selektoren wie die folgenden erstellen:

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

Ich habe ein unglaublich einfaches Plugin (5 Codezeilen) für genau diese Funktionalität geschrieben:

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

Sie können effektiv sagen "Dieses Element abrufen oder, falls dieses Element nicht vorhanden ist, dieses Element verwenden". Zum Beispiel:

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

Während die akzeptierte Antwort ähnliche Funktionen bietet, werden beide Selektoren zurückgegeben, wenn beide Selektoren (vor und nach dem Komma) vorhanden sind.

Ich hoffe, es ist hilfreich für alle, die über Google auf dieser Seite landen könnten.

Von Richard Powell
quelle
4
So funktioniert der boolesche ODER-Operator nicht. Wenn beide Selektoren Elemente zurückgeben, sollte der OR-Operator alle und nicht nur die Elemente des ersten Selektors zurückgeben. Ihr Plugin sollte "ifEmpty" oder "else" oder so ähnlich heißen.
Alp
13
@Alp: Betrachten Sie das Verhalten von "a" || "b"vs. null || "b"in Vanilla JS. Wenn wir hier dasselbe Verhalten anwenden, $(a).or(b)sollte es zurückkehren, $(a)falls es existiert, andernfalls sollte es zurückkehren $(b). Ich glaube nicht, dass an dieser Nomenklatur etwas falsch ist, da das "oder" dem Verhalten des JS "||" entspricht. (oder) Betreiber.
FtDRbwLXw6
4
Ich sehe es auch als or. Was andere reden, ist eher eine concatoder eine mergeHandlung.
Léon Pelletier
1
Persönlich würde ich dies nicht "oder" nennen, da dies zu Verwirrung führen kann (auch wenn es technisch korrekt sein kann, da es sich um eine besondere Art von Wenn / Oder handelt). Dies ist
praktisch
Der Begriff "xor" (exklusiv oder) ist der genaue Begriff, aber häufig suchen oder suchen Menschen nach xor, da xor im Allgemeinen allgemein eine bestimmte Art von "oder" ist.
Liljoshu
17

Wenn Sie das Standardkonstrukt von element = element1 || verwenden möchten Element2, bei dem JavaScript das erste zurückgibt, das wahr ist, können Sie genau das tun:

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

Dies würde das erste Element zurückgeben, das tatsächlich gefunden wird. Ein besserer Weg wäre jedoch wahrscheinlich, das Kommakonstrukt jQuery-Selektor (das ein Array gefundener Elemente zurückgibt) auf folgende Weise zu verwenden:

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

Dies gibt das erste gefundene Element zurück.

Ich benutze das von Zeit zu Zeit, um entweder ein aktives Element in einer Liste oder ein Standardelement zu finden, wenn es kein aktives Element gibt. Zum Beispiel:

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

Dies wird jedes Li mit einer Klasse von aktiven oder, falls es keine gibt, nur das letzte Li zurückgeben.

Beides wird funktionieren. Es gibt jedoch potenzielle Leistungseinbußen, wie die || stoppt die Verarbeitung, sobald etwas Wahres gefunden wird, während der Array-Ansatz versucht, alle Elemente zu finden, auch wenn er bereits eines gefunden hat. Dann wieder mit dem || Konstrukt kann möglicherweise Leistungsprobleme haben, wenn es mehrere Selektoren durchlaufen muss, bevor es das zurückgegebene findet, da es das Haupt-jQuery-Objekt für jedes aufrufen muss (ich weiß wirklich nicht, ob dies ein Leistungseinbruch ist oder nicht). es scheint nur logisch, dass es sein könnte). Im Allgemeinen verwende ich jedoch den Array-Ansatz, wenn der Selektor eine ziemlich lange Zeichenfolge ist.

Ken Dickinson
quelle
Ich denke, find ('. SomethingToBeFound, .somethingElseToBeFound') ist nicht dasselbe wie || konstruieren. Wenn Sie herausfinden, ob .somethingElseToBeFound vor .somethingToBeFound im DOM ist, wird es zurückgegeben, selbst wenn .somethingToBeFound vorhanden ist.
Remo
0

Endlich habe ich Hack gefunden, wie es geht:

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

(wählt div mit Klasse classAODER classBmit direkter untergeordneter Spanne aus)

Midlan
quelle
-2

Daniel A. White Solution eignet sich hervorragend für Klassen.

Ich habe eine Situation, in der ich Eingabefelder wie donee_1_card finden musste, wobei 1 ein Index ist.

Meine Lösung war

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

Obwohl ich nicht sicher bin, wie optimal es ist.

FDussault
quelle