blob: 8e89eb8534f6a18eb28f64e819a1227a33b6d059 (
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
---
title: Element.closest()
slug: Web/API/Element/closest
tags:
- API
- DOM
- Element
- Method
- Reference
translation_of: Web/API/Element/closest
---
<div>
<p>{{APIRef('Shadow DOM')}}</p>
</div>
<p><code><strong>Element.closest()</strong></code> 方法用来获取:匹配特定选择器且离当前元素最近的祖先元素(也可以是当前元素本身)。如果匹配不到,则返回 <code>null</code>。</p>
<h2 id="Syntax" name="Syntax">语法</h2>
<pre class="syntaxbox">var <var>closestElement</var><em> = </em><var>targetElement</var>.closest(<em>selectors</em>);
</pre>
<h3 id="参数">参数</h3>
<ul>
<li><em>selectors</em> 是指定的选择器,比如 <code>"p:hover, .toto + q"</code>。</li>
</ul>
<h3 id="返回值">返回值</h3>
<ul>
<li><em>elt</em> 是查询到的祖先元素,也可能是 <code>null</code>。</li>
</ul>
<h3 id="异常">异常</h3>
<ul>
<li>如果传入的选择器不合法,则抛出 {{exception("SyntaxError")}} 异常。</li>
</ul>
<h2 id="示例">示例</h2>
<h3 id="HTML">HTML</h3>
<pre class="brush: html"><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></pre>
<h3 id="JavaScript">JavaScript</h3>
<pre class="brush: js">var el = document.getElementById('div-03');
var r1 = el.closest("#div-02");
// 返回 id 为 div-02 的那个元素
var r2 = el.closest("div div");
// 返回最近的拥有 div 祖先元素的 div 祖先元素,这里的话就是 div-03 元素本身
var r3 = el.closest("article > div");
// 返回最近的拥有父元素 article 的 div 祖先元素,这里的话就是 div-01
var r4 = el.closest(":not(div)");
// 返回最近的非 div 的祖先元素,这里的话就是最外层的 article</pre>
<h2 id="Polyfill" name="Polyfill">兼容</h2>
<p>部分浏览器并不支持<code>Element.closest()</code>,但却支持了<code>element.matches()</code>(或拥有私有前缀,如IE9+),一个polyfill案例:</p>
<pre class="brush: js">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;
} while (el !== null);
return null;
};</pre>
<p>然而,如果你需要兼容到IE8,那么随后这个polyfill将会非常缓慢地运行到结束。并且,IE8只支持CSS2.1的选择器,并且使网页运行非常缓慢。</p>
<pre class="brush: js">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;
};
}
</pre>
<h2 id="Specification" name="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" name="Browser_compatibility">浏览器兼容性</h2>
<p>{{Compat("api.Element.closest")}}</p>
<h3 id="兼容性说明">兼容性说明</h3>
<ul>
<li>当在 Edge 15-18 里使用 <code>document.createElement(tagName).closest(tagName)</code> ,如果元素不是第一个(直接地或间接地)连接到上下文对象的话将会返回 <code>null</code> ,例如在一般情况下 DOM 中的 <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Document" title="The Document interface represents any web page loaded in the browser and serves as an entry point into the web page's content, which is the DOM tree.">Document</a></code> 对象。</li>
</ul>
<h2 id="相关链接">相关链接</h2>
<ul>
<li>{{domxref("Element")}} 接口.</li>
<li>
<div class="syntaxbox"><a href="/zh-CN/docs/Web/Guide/CSS/Getting_started/Selectors">选择器语法</a></div>
</li>
<li>
<div class="syntaxbox">其他相关选择器方法: {{domxref("element.querySelector()")}} and {{domxref("element.matches()")}}.</div>
</li>
</ul>
|