How to Find Any Closest Element in JavaScript

How to Find Any Closest Element in JavaScript

Searching DOM nodes in any direction
Ferenc Almasi β€’ 2023 January 26 β€’ πŸ“– 3 min read

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>
element.closest.js Finding closest DOM elements using the closest method
Copied to clipboard!

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
}
closest.js Finding closest DOM elements in any direction
Copied to clipboard!
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScript

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>
closest works in all directions
Copied to clipboard!

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.

Did you find this page helpful?
πŸ“š More Webtips
Frontend Course Dashboard
Master the Art of Frontend
  • check Unlimited access to hundred of tutorials
  • check Access to exclusive interactive lessons
  • check Remove ads to learn without distractions
Become a Pro

Recommended