JQuery ИЛИ Селектор?

325

Мне интересно, есть ли способ иметь логику "ИЛИ" в селекторах jQuery. Например, я знаю, что элемент является потомком элемента с классом classA или classB, и я хочу сделать что-то подобное elem.parents('.classA or .classB'). Предоставляет ли jQuery такую ​​функциональность?

Суан
источник

Ответы:

494

Используйте запятую.

'.classA, .classB'

Вы можете опустить пространство.

Даниэль А. Уайт
источник
43
Следует отметить, что на самом деле это не «или» селектор, а скорее как несколько селекторов в одном.
Алекс
49
@alex: но он не выберет один и тот же элемент дважды (как оператор конкатенации). Это действительно селектор ИЛИ, потому что он создает СОЮЗ из двух или более множеств (тогда как И - это пересечение).
Клет
Спасибо, это работает. Из-за упущения в отладке я подумал, что использование запятой означает «И».
Суан
38
ANDбудет .classA.classB.
Дэниел А. Уайт
2
Это на самом деле зависит от того, что подразумевал первоначальный вопрос ... то есть: классически оператор 'или' будет закорочен. Таким образом, оператор 'или' на языке jquery, возможно, тоже может быть закорочен.
Мэтью
71

Использование запятой может быть недостаточным, если у вас есть несколько объектов jQuery, которые необходимо объединить.

Метод .add () добавляет выбранные элементы в набор результатов:

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

Это более многословно, чем '.classA, .classB', но позволяет вам создавать более сложные селекторы, как показано ниже:

// (classA which has <p> descendant) OR (<div> ancestors of classB)
jQuery('.classA').has('p').add(jQuery('.classB').parents('div'));
горная вершина
источник
22

Я написал невероятно простой (5 строк кода) плагин именно для этой функциональности:

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

Это позволяет вам эффективно сказать «получить этот элемент, или, если этот элемент не существует, используйте этот элемент». Например:

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

Хотя принятый ответ обеспечивает аналогичную функциональность, если оба селектора (до и после запятой) существуют, оба селектора будут возвращены.

Я надеюсь, что это окажется полезным для тех, кто может попасть на эту страницу через Google.

Ричард Пауэлл
источник
4
Это не то, как работает логический оператор ИЛИ. Если оба селектора возвращают элементы, оператор OR должен возвращать все из них, а не только элементы первого селектора. Ваш плагин должен называться «ifEmpty» или «else» или что-то в этом роде.
Alp
13
@Alp: рассмотрим поведение "a" || "b"vs. null || "b"в ванильном JS. Если мы применяем такое же поведение здесь, $(a).or(b)должен вернуться, $(a)если он существует, в противном случае он должен вернуться $(b). Я не думаю, что с этой номенклатурой что-то не так, поскольку "или" соответствует поведению JS "||" (или) оператор.
FtDRbwLXw6
4
Я тоже вижу это как or. То, о чем говорят другие, больше похоже на действие concatили mergeдействие.
Леон Пеллетье
1
Лично я бы не назвал это «или», так как это может привести к путанице (даже если это технически правильно, так как это особый вид if / или). Это фактически нулевое слияние, которое называется разными вещами и имеет разные операторы на разных языках: en.wikipedia.org/wiki/Null_coalescing_operator
JanErikGunnar
Термин «xor» (исключительный или) будет точным термином, но часто люди ищут или ищут xor, поскольку xor, как правило, в общих чертах, является специфическим типом «или».
Лильёшу
17

Если вы хотите использовать стандартную конструкцию element = element1 || element2, где JavaScript вернет первое правдивое, вы можете сделать именно это:

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

который возвратил бы первый элемент, который фактически найден. Но, возможно, лучшим способом было бы использовать запятую конструкцию селектора jQuery (которая возвращает массив найденных элементов) следующим образом:

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

который вернет первый найденный элемент.

Я использую это время от времени, чтобы найти активный элемент в списке или какой-либо элемент по умолчанию, если нет активного элемента. Например:

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

который вернет любой li с классом active или, если его нет, просто вернет последний li.

Либо будет работать. Есть потенциальные потери производительности, хотя, как || остановит обработку, как только найдет что-то правдивое, тогда как подход с использованием массива попытается найти все элементы, даже если он уже нашел один. Опять же, используя || У конструкции потенциально могут быть проблемы с производительностью, если ей придется пройти через несколько селекторов перед тем, как найти тот, который он вернет, потому что он должен вызывать основной объект jQuery для каждого (я действительно не знаю, является ли это падением производительности или нет, это просто кажется логичным, что это может быть). В целом, однако, я использую подход массива, когда селектор является довольно длинной строкой.

Кен Дикинсон
источник
Я думаю, что find ('.thingToBeFound, .somethingElseToBeFound') не совпадает с || построить. Потому что найти, если .somethingElseToBeFound находится в DOM до .somethingToBeFound, он будет возвращен, даже если .somethingToBeFound существует.
Ремо
0

Наконец-то я нашел хак, как это сделать:

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

(выбирает div с классом classAOR classBс прямым дочерним диапазоном)

midlan
источник
-2

Daniel A. White Solution отлично работает на уроках.

У меня возникла ситуация, когда мне нужно было найти поля ввода, такие как donee_1_card, где 1 - индекс.

Мое решение было

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

Хотя я не уверен, насколько это оптимально.

FDussault
источник