Element.closest()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

Метод Element.closest() возвращает ближайший родительский элемент (или сам элемент), который соответствует заданному CSS-селектору или null, если таковых элементов вообще нет.

Синтаксис

var elt = element.closest(selectors);
  • selectors - строка, а точнее DOMString, содержащая CSS-селектор, к примеру: "#id", ".class", "div" ...
  • Результат - элемент DOM (Element), либо null.

Исключения

SYNTAX_ERR

Указанный css-селектор не является допустимым ("/=21=1", "&@*#", "%'54523" и т.п. приведут к ошибке).

Пример

<div id="block" title="Я - блок">
    <a href="#">Я ссылка в никуда</a>
    <a href="http://site.ru">Я ссылка на сайт</a>
    <div>
       <div id="too"></div>
    </div>
</div>

Думаю, стоит рассмотреть несколько примеров:

js
var div = document.querySelector("#too"); //Это элемент от которого мы начнём поиск

div.closest("#block"); //Результат - самый первый блок древа выше
div.closest("div"); //Сам блок #too и будет результатом, так как он подходит под селектор "div"
div.closest("a"); //null - В предках #too нет ни одного тега "a"!
div.closest("div[title]"); //#block - так как ближе нет блоков с атрибутом title.

Полифил #1 (рекурсивный метод)

Для браузеров не поддерживающих Element.closest(), но позволяющих использовать element.matches() (или префиксный эквивалент) есть полифил:

js
(function (ELEMENT) {
  ELEMENT.matches =
    ELEMENT.matches ||
    ELEMENT.mozMatchesSelector ||
    ELEMENT.msMatchesSelector ||
    ELEMENT.oMatchesSelector ||
    ELEMENT.webkitMatchesSelector;
  ELEMENT.closest =
    ELEMENT.closest ||
    function closest(selector) {
      if (!this) return null;
      if (this.matches(selector)) return this;
      if (!this.parentElement) {
        return null;
      } else return this.parentElement.closest(selector);
    };
})(Element.prototype);

Полифил #2 (через цикл)

Тем не менее, если вам требуется поддержка IE 8, вы можете использовать следующий полифил. Имейте ввиду - этот способ позволяет использовать CSS селекторы только уровня 2.1 и может жутко тормозить.

js
(function (e) {
  e.closest =
    e.closest ||
    function (css) {
      var node = this;
      while (node) {
        if (node.matches(css)) return node;
        else node = node.parentElement;
      }
      return null;
    };
})(Element.prototype);

Спецификации

Specification
DOM
# ref-for-dom-element-closest①

Совместимость с браузерами

Report problems with this compatibility data on GitHub
desktopmobile
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
closest

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support

Смотрите также