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", "&@*#", "%'54523" и т.п. приведут к ошибке).</em></dd>
</dl>
<h2 id="Example">Пример</h2>
<pre><div id="block" title="Я - блок">
<a href="#">Я ссылка в никуда</a>
<a href="http://site.ru">Я ссылка на сайт</a>
<div>
<div id="too"></div>
</div>
</div>
</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("api.Element.closest")}}</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>
|