How to Find Any Closest Element in JavaScript
Finding the closest DOM element to a selector in JavaScript cannot be achieved by only using the closest
method. The closest
method only traverses the parents of the element, while leaving siblings out of the search.
<main class="content">
<div class="tooltip-container">
<span class="tooltip">...</span>
<span class="tooltip-backdrop">...</span>
</div>
<button class="cta">
<img class="cta-icon" />
</button>
</main>
<script>
const element = document.querySelector('.tooltip')
// βοΈ Works with parents only
console.log(element.closest('.tooltip-container'))
console.log(element.closest('.content'))
// β No sibling, sibling of parent, or children of sibling support
console.log(element.closest('.tooltip-backdrop'))
console.log(element.closest('.cta'))
console.log(element.closest('.cta-icon'))
</script>
While closest
will work for the first two examples, it doesnβt cater to the other three, regardless of the fact that the third example is also the closest element to the selector. To also include siblings in the search, we need to create a custom function:
const closest = (to, selector) => {
let currentElement = document.querySelector(to)
let returnElement
while (currentElement.parentNode && !returnElement) {
currentElement = currentElement.parentNode
returnElement = currentElement.querySelector(selector)
}
return returnElement
}
How it Works
To find the closest element to a selector in JavaScript in any direction, we need to traverse parent elements and try to query for the searched element within each parent. This is what the above function achieves.
In case we have a parent element, we store it as our currentElement
, and try to query for the searched element within it using currentElement.querySelector
. As long as we have a parent element, and donβt have a returnElement
, we keep on moving up the DOM tree one level at a time.
<main class="content">
<div class="tooltip-container">
<span class="tooltip">...</span>
<span class="tooltip-backdrop">...</span>
</div>
<button class="cta">
<img class="cta-icon" />
</button>
</main>
<script>
const elementSelector = '.tooltip'
// βοΈ Outputs the same as .closest
console.log(closest(elementSelector, '.tooltip-container'))
console.log(closest(elementSelector, '.content'))
// βοΈ Works with elements in any other directions
console.log(closest(elementSelector, '.tooltip-backdrop'))
console.log(closest(elementSelector, '.cta'))
console.log(closest(elementSelector, '.cta-icon'))
</script>
Using the above function for the same example, it will now find the closest elements in all directions. Just as for closest
, it will get the correct elements for the first two examples, while for the other ones, it will get the closest sibling, and as shown above, it can even get child elements of other siblings.
Rocket Launch Your Career
Speed up your learning progress with our mentorship program. Join as a mentee to unlock the full potential of Webtips and get a personalized learning experience by experts to master the following frontend technologies: