Check if any ancestor has a class using jQuery
Asked Answered
K

3

186

Is there any way in jQuery to check if any parent, grand-parent, great-grand-parent has a class.

I have a markup structure that has left me doing this sort of thing in the code:

$(elem).parent().parent().parent().parent().hasClass('left')

However, for code readability i'd like to avoid this sort of thing. Is there any way to say "any parent/grandparent/great-grand-parent has this class"?

I am using jQuery 1.7.2.

Kerriekerrigan answered 13/6, 2013 at 10:31 Comment(1)
#16864417 - in case someone want's to do it without jQueryIntersex
U
356
if ($elem.parents('.left').length) {

}
Unfriendly answered 13/6, 2013 at 10:32 Comment(2)
Thanks, just what I needed! For the record, while the practice of treating .length as a truthy value is quite prolific in JS, it is far clearer and easier to understand .length > 0Copperas
Here's the link to jQuery .parents() documentationAlysonalysoun
W
95

There are many ways to filter for element ancestors.

if ($elem.closest('.parentClass').length /* > 0*/) {/*...*/}
if ($elem.parents('.parentClass').length /* > 0*/) {/*...*/}
if ($elem.parents().hasClass('parentClass')) {/*...*/}
if ($('.parentClass').has($elem).length /* > 0*/) {/*...*/}
if ($elem.is('.parentClass *')) {/*...*/} 

Beware, closest() method includes element itself while checking for selector.

Alternatively, if you have a unique selector matching the $elem, e.g #myElem, you can use:

if ($('.parentClass:has(#myElem)').length /* > 0*/) {/*...*/}
if(document.querySelector('.parentClass #myElem')) {/*...*/}

If you want to match an element depending any of its ancestor class for styling purpose only, just use a CSS rule:

.parentClass #myElem { /* CSS property set */ }
Washtub answered 13/6, 2013 at 10:35 Comment(5)
I might venture to say (without testing this) that this method is better. Elem.parents will traverse the entire parent dom strucutre, where closest() should (probably) stop once it finds the nearest parent with that element and is therefore more efficient. This is an uneducated guess. I usually use closest(). Sounds like I found a new topic to research for my blog! :PWolf
@Wolf yes it is but it's quite recent. I mean in older jq version, AFAIK, this wasn't the case. Parents loop was not break on first matched parent using closest(), but now it is. (don't know since which jq version but i'm pretty sure to be correct on this statement)Washtub
Good to know, thanks for the info. Weird that they wouldn't have built the break in from the first version.Wolf
when there are no parents to be found, parents() is faster than closest() jsperf.com/closest-vs-parents-foobarUnfriendly
@Unfriendly Quite interresting indeed, thx for the input! BTW, re-reading the question, Is there any way in jQuery to check if any parent,..., closest() check for element itself so this is not really answering question, OP could wish to explecitely exclude the element itself, so ya, answer was to use .parents()Washtub
P
11

You can use parents method with specified .class selector and check if any of them matches it:

if ($elem.parents('.left').length != 0) {
    //someone has this class
}
Promote answered 13/6, 2013 at 10:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.