jQuery OR Selector?


325

Мені цікаво, чи існує спосіб мати логіку "АБО" у селекторах jQuery. Наприклад, я знаю, що елемент є або нащадком елемента з класом classA, або classB, і я хочу зробити щось подібне elem.parents('.classA or .classB'). Чи надає jQuery таку функціональність?

Відповіді:


494

Скористайтеся комою.

'.classA, .classB'

Ви можете пропустити простір.


43
Слід зазначити, що це насправді не селектор "чи", більше схожий на кілька селекторів в одному.
alex

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
Ось так не працює оператор булевого АБО. Якщо обидва селектори повертають елементи, оператор АБО повинен повернути всі вони, а не лише елементи першого селектора. Ваш плагін має бути названий "ifEmpty" або "else" або щось подібне.
Альп

13
@Alp: Розгляньте поведінку "a" || "b"проти null || "b"ванілі JS. Якщо ми застосуємо ту саму поведінку, $(a).or(b)слід повернутися, $(a)якщо вона існує, інакше вона повинна повернутися $(b). Я не думаю, що в цій номенклатурі нічого поганого, оскільки "або" відповідає поведінці СВ "||" (або) оператора.
FtDRbwLXw6

4
Я також бачу це як or. Те, про що інші говорять, більше схоже на дії concatчи mergeдії.
Леон Пелтьє

1
Особисто я б не називав це "чи", оскільки це може призвести до плутанини (навіть якщо технічно це може бути правильним, оскільки це особливий вид, якщо / або). Це фактично нульова коалесценція, яку називають різними речами та мають різні оператори на різних мовах: en.wikipedia.org/wiki/Null_coalescing_operator
JanErikGunnar

Термін "xor" (ексклюзивний або) був би точним терміном, але часто люди шукають або шукають xor, оскільки xor, як правило, є певним типом "або".
liljoshu

17

Якщо ви хочете використовувати стандартну конструкцію element = element1 || element2, де JavaScript поверне першу, що є truthy, ви можете зробити саме це:

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

який би повернув перший елемент, який фактично знайдений. Але кращим способом, мабуть, було б використання конструкції селектора кома jQuery (яка повертає масив знайдених елементів) таким чином:

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

який поверне перший знайдений елемент.

Я використовую це час від часу, щоб знайти або активний елемент у списку, або якийсь елемент за замовчуванням, якщо немає активного елемента. Наприклад:

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

який поверне будь-який li з класом активних або, якщо таких не буде, просто поверне останній li.

Або буде працювати. Однак можливі покарання за виконання, як || припинить обробку, як тільки знайде щось правдоподібне, тоді як підхід масиву спробує знайти всі елементи, навіть якщо він вже знайшов його. Потім знову, використовуючи || конструкт потенційно може мати проблеми з продуктивністю, якщо йому доведеться пройти кілька селекторів, перш ніж знайти той, який він поверне, тому що він повинен викликати головний об’єкт jQuery для кожного (я дійсно не знаю, чи це хіт продуктивності чи ні, просто логічно здається, що це могло бути). Однак загалом я використовую підхід масиву, коли селектор є досить довгим рядком.


Я думаю, що знайти ('. SomethingToBeFound, .somethingElseToBeFound') не збігається з || побудувати. Тому що знайдіть, якщо .somethingElseToBeFound знаходиться в DOM раніше .somethingToBeFound, воно буде повернуто, навіть якщо існує .somethingToBeFound.
видалити

0

Нарешті я знайшов хак, як це зробити:

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

(вибирає div з класом classAАБО classBіз прямим дочірнім періодом)


-2

Daniel A. White Solution чудово підходить для занять.

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

Моє рішення було

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

Хоча я не впевнений, наскільки це оптимально.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.