Find the closest ancestor element that has a specific class
How can I find an element's ancestor that is closest up the tree that has a particular class, in pure JavaScript? For example, in a tree like so:
<div class="far ancestor">
<div class="near ancestor">
<p>Where am I?</p>
</div>
</div>
Then I want div.near.ancestor
if I try this on the p
and search for ancestor
.
Solution 1:
Update: Now supported in most major browsers
document.querySelector("p").closest(".near.ancestor")
Note that this can match selectors, not just classes
https://developer.mozilla.org/en-US/docs/Web/API/Element.closest
For legacy browsers that do not support closest()
but have matches()
one can build selector-matching similar to @rvighne's class matching:
function findAncestor (el, sel) {
while ((el = el.parentElement) && !((el.matches || el.matchesSelector).call(el,sel)));
return el;
}
Solution 2:
This does the trick:
function findAncestor (el, cls) {
while ((el = el.parentElement) && !el.classList.contains(cls));
return el;
}
The while loop waits until el
has the desired class, and it sets el
to el
's parent every iteration so in the end, you have the ancestor with that class or null
.
Here's a fiddle, if anyone wants to improve it. It won't work on old browsers (i.e. IE); see this compatibility table for classList. parentElement
is used here because parentNode
would involve more work to make sure that the node is an element.