Replace jQuery .closest() with Vanilla JavaScript
Transitioning away from jQuery often leaves developers looking for
modern, native alternatives to its most popular DOM traversal methods.
This guide explains how modern vanilla JavaScript completely replaces
the jQuery .closest() method using the standard
Element.closest() API, detailing its syntax, behavior,
event delegation patterns, and browser support.
The Native Alternative:
Element.closest()
Modern browsers provide a native DOM method called
Element.closest(). It works virtually identically to
jQuery's implementation: it checks the current element against a
specified CSS selector, and if it does not match, it traverses up the
DOM tree through ancestor elements until a match is found. If no match
is found, it returns null.
Syntax Comparison
jQuery
// jQuery
const closestCard = $('.child-element').closest('.card');Vanilla JavaScript
// Vanilla JS
const child = document.querySelector('.child-element');
const closestCard = child.closest('.card');Key Differences and Behavior
- Return Value:
- jQuery returns a jQuery object, which is always truthy, even if no
element matched (in which case its
.lengthis0). - Vanilla JS returns the matching DOM element, or
nullif no match exists. Always check fornullbefore interacting with the result.
- jQuery returns a jQuery object, which is always truthy, even if no
element matched (in which case its
const button = document.querySelector('button');
const modal = button.closest('.modal');
if (modal) {
modal.classList.add('is-active');
}- Self-Matching: Like jQuery, native
closest()tests the calling element itself first before inspecting parent elements. If the element calling the method matches the selector, that element is returned immediately.
Event Delegation with
Element.closest()
One of the most common use cases for .closest() in
jQuery is event delegation. In vanilla JavaScript, you can achieve the
same behavior using the event.target property inside a
standard event listener:
document.addEventListener('click', (event) => {
// Find closest button ancestor or the button itself
const button = event.target.closest('.action-btn');
// If the click happened outside of any .action-btn, exit
if (!button) return;
// Perform action using the matched element
console.log('Button clicked:', button.dataset.id);
});This pattern handles nested elements inside buttons (such as
<span> tags or SVG icons) seamlessly without needing
separate event listeners on every item.
Browser Compatibility
The native Element.closest() method is supported across
all modern browsers, including Chrome, Firefox, Safari, and Edge.
Polyfills are only required if you need to support legacy browsers such
as Internet Explorer 11.