I am wondering if there is a way to have "OR" logic in jQuery selectors. For example, I know an element is either a descendant of an element with class 开发者_StackOverflow社区classA or classB, and I want to do something like elem.parents('.classA or .classB')
. Does jQuery provide such functionality?
Use a comma.
'.classA, .classB'
You may choose to omit the space.
Using a comma may not be sufficient if you have multiple jQuery objects that need to be joined.
The .add() method adds the selected elements to the result set:
// classA OR classB
jQuery('.classA').add('.classB');
It's more verbose than '.classA, .classB'
, but lets you build more complex selectors like the following:
// (classA which has <p> descendant) OR (<div> ancestors of classB)
jQuery('.classA').has('p').add(jQuery('.classB').parents('div'));
I have written an incredibly simple (5 lines of code) plugin for exactly this functionality:
http://byrichardpowell.github.com/jquery-or/
It allows you to effectively say "get this element, or if that element doesnt exist, use this element". For example:
$( '#doesntExist' ).or( '#exists' );
Whilst the accepted answer provides similar functionality to this, if both selectors (before & after the comma) exist, both selectors will be returned.
I hope it proves helpful to anyone who might land on this page via google.
If you're looking to use the standard construct of element = element1 || element2 where JavaScript will return the first one that is truthy, you could do exactly that:
element = $('#someParentElement .somethingToBeFound') || $('#someParentElement .somethingElseToBeFound');
which would return the first element that is actually found. But a better way would probably be to use the jQuery selector comma construct (which returns an array of found elements) in this fashion:
element = $('#someParentElement').find('.somethingToBeFound, .somethingElseToBeFound')[0];
which will return the first found element.
I use that from time to time to find either an active element in a list or some default element if there is no active element. For example:
element = $('ul#someList').find('li.active, li:first')[0]
which will return any li with a class of active or, should there be none, will just return the last li.
Either will work. There are potential performance penalties, though, as the || will stop processing as soon as it finds something truthy whereas the array approach will try to find all elements even if it has found one already. Then again, using the || construct could potentially have performance issues if it has to go through several selectors before finding the one it will return, because it has to call the main jQuery object for each one (I really don't know if this is a performance hit or not, it just seems logical that it could be). In general, though, I use the array approach when the selector is a rather long string.
Finally I've found hack how to do it:
div:not(:not(.classA,.classB)) > span
(selects div with class classA
OR classB
with direct child span)
Daniel A. White Solution works great for classes.
I've got a situation where I had to find input fields like donee_1_card where 1 is an index.
My solution has been
$("input[name^='donee']" && "input[name*='card']")
Though I am not sure how optimal it is.
精彩评论