aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/api/element/closest/index.html
blob: 2cf55e83afdbeaf10494af280d5496c067fb0367 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
---
title: Element.closest()
slug: Web/API/Element/closest
tags:
  - API
  - DOM
  - Element
  - Method
  - Reference
translation_of: Web/API/Element/closest
---
<div>{{APIRef("DOM")}}</div>

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

<h2 id="Syntax">Синтаксис</h2>

<pre class="syntaxbox">var <em>elt =</em><em> element</em>.closest(<em>selectors</em>);
</pre>

<ul>
 <li><strong><code>selectors</code><em></em></strong>строка, а точнее {{domxref("DOMString")}}<code><em>, </em></code>содержащая CSS-селектор, к примеру: <em><strong>"#id", ".class", "div"</strong>...</em></li>
 <li>Результат - элемент DOM ({{domxref("Element")}}), либо null.</li>
</ul>

<h2 id="Исключения">Исключения</h2>

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

<h2 id="Example">Пример</h2>

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

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

<pre class="brush: 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.

</pre>

<h2 id="Полифил_1_рекурсивный_метод">Полифил #1 (рекурсивный метод)</h2>

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

<pre class="brush: 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));</pre>

<h2 id="Specification">Полифил #2 (через цикл)</h2>

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

<pre class="brush: js">(function(e){
 e.closest = e.closest || function(css){
   var node = this;
 <code class="language-javascript"><span class="keyword token">
   while</span> <span class="punctuation token">(</span>node<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">      if</span> <span class="punctuation token">(</span>node<span class="punctuation token">.</span><span class="function token">matches</span><span class="punctuation token">(</span>css<span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="keyword token">return</span> node<span class="punctuation token">;</span>
      <span class="keyword token">else</span> node <span class="operator token">=</span> node<span class="punctuation token">.</span>parentElement<span class="punctuation token">;</span>
   <span class="punctuation token">}</span>
<span class="keyword token">   return</span> <span class="keyword token">null</span><span class="punctuation token">;</span></code>
 }
})(Element.prototype);</pre>

<h2 id="Specification">Спецификация</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('DOM WHATWG', '#dom-element-closest', 'Element.closest()')}}</td>
   <td>{{Spec2('DOM WHATWG')}}</td>
   <td>Initial definition.</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Совместимость с браузерами</h2>

<div>{{Compat}}</div>

<div>
<h3 id="Примечания_совместимости">Примечания совместимости</h3>

<ul>
 <li>В Edge <code>document.createElement(tagName).closest(tagName)</code> возвращает <code>null</code>, если элемент ещё не привязан в DOM.</li>
</ul>

<h2 id="Смотрите_также">Смотрите также</h2>

<ul>
 <li>Интерфейс {{domxref("Element")}}.</li>
 <li>
  <p><a href="https://developer.mozilla.org/ru/docs/Learn/CSS/Introduction_to_CSS/Selectors">Синтаксис селекторов</a></p>
 </li>
 <li>
  <p>Другие методы, принимающие селекторы: {{domxref("element.querySelector()")}} и {{domxref("element.matches()")}}.</p>
 </li>
</ul>
</div>