This is an experimental technology
Check the Browser compatibility table carefully before using this in production.
The Element.closest()
method returns the closest ancestor of the current element (or the current element itself) which matches the selectors given in parameter. If there isn't such an ancestor, it returns null
.
var elt = element.closest(selectors);
DOMString
containing a selector list like "p:hover, .toto + q"
Element
at the top of the tree of elements to be dealt with.Element
which is the closest ancestor of the selected elements. It may be null.SyntaxError
is thrown if the selectors is not a valid selector list string.<article> <div id="div-01">Here is div-01 <div id="div-02">Here is div-02 <div id="div-03">Here is div-03</div> </div> </div> </article>
var el = document.getElementById('div-03'); var r1 = el.closest("#div-02"); // returns the element with the id=div-02 var r2 = el.closest("div div"); // returns the closest ancestor which is a div in div, here is div-03 itself var r3 = el.closest("article > div"); // returns the closest ancestor which is a div and has a parent article, here is div-01 var r4 = el.closest(":not(div)"); // returns the closest ancestor which is not a div, here is the outmost article
For browsers that do not support Element.closest()
, but carry support for element.matches()
(or a prefixed equivelent, meaning IE9+), a polyfill exists:
if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; if (!Element.prototype.closest) Element.prototype.closest = function(s) { var el = this; if (!document.documentElement.contains(el)) return null; do { if (el.matches(s)) return el; el = el.parentElement || el.parentNode; } while (el !== null && el.nodeType === 1); return null; };
However, if you really do require IE 8 support, then the following polyfill will do the job very slowly, but eventually. However, it will only support CSS 2.1 selectors in IE 8, and it can cause severe lag spikes in production websites.
if (window.Element && !Element.prototype.closest) { Element.prototype.closest = function(s) { var matches = (this.document || this.ownerDocument).querySelectorAll(s), i, el = this; do { i = matches.length; while (--i >= 0 && matches.item(i) !== el) {}; } while ((i < 0) && (el = el.parentElement)); return el; }; }
Specification | Status | Comment |
---|---|---|
DOM The definition of 'Element.closest()' in that specification. | Living Standard | Initial definition. |
Feature | Chrome | Edge | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic support | 41 | 15 | 35.0 (35.0) | No support | 28 | 9 |
Feature | Android | Edge | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | ? | ? | 35.0 (35.0) | No support | ? | 9.0 |
Element
interface.element.querySelector()
and element.matches()
.
© 2005–2018 Mozilla Developer Network and individual contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/element/closest