blob: 17a6bed612a32557bad4cca3eefaee7084007e73 (
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
|
---
title: Resize Observer API
slug: Web/API/Resize_Observer_API
translation_of: Web/API/Resize_Observer_API
---
<p>{{DefaultAPISidebar("Resize Observer API")}}</p>
<p>Resize Observer API提供了一种高性能的机制,通过该机制,代码可以监视元素的大小更改,并且每次大小更改时都会向观察者传递通知。</p>
<h2 id="概念和使用">概念和使用</h2>
<p>存在大量的响应式设计(以及其他相关)技术,它们可以响应元素大小的变化,但是以前,它们的实现常常很笨拙或者说生硬。</p>
<p>举个例子,当视口更改大小时, <a href="/en-US/docs/Web/CSS/Media_Queries">媒介查询</a> / {{domxref("window.matchMedia")}} 非常适合在特定点更新布局,但是如果要响应于特定元素的大小更改而更改布局,该元素又不是外部容器时,该怎么办?</p>
<p>为此,一种有限的解决方案是监听对适当事件的更改,该事件会提示您对更改大小感兴趣的元素 (例如 window <a href="/en-US/docs/Web/API/Window/resize_event">resize event</a>),然后找出该元素之后新的尺寸或其他功能,例如,使用{{domxref("Element.getBoundingClientRect")}} 或者{{domxref("Window.getComputedStyle")}},来调整大小。</p>
<p>这样的解决方案仅适用于有限的场景,对性能不利(不断调用上述方法会导致性能严重下降),并且在不更改浏览器窗口大小的情况下通常不起作用。</p>
<p>Resize Observer API提供了一种解决此类问题的解决方案,此外,它还使您能够轻松观察和响应元素内容或边框的大小变化,并以高效的方式做出响应。 它为Web平台中经常讨论的缺少<a href="https://www.xanthir.com/b4PR0">element queries</a> 提供了JavaScript解决方案。</p>
<p>用法很简单,并且与其他观察者(例如 <a href="/en-US/docs/Web/API/PerformanceObserver">Performance Observer</a> 或者 <a href="/en-US/docs/Web/API/Intersection_Observer_API">Intersection Observer</a> )— 几乎相同,您可以使用 <code><a href="/en-US/docs/Web/API/ResizeObserver/ResizeObserver">ResizeObserver()</a></code>构造函数创建一个新的{{domxref("ResizeObserver")}} ,然后使用 {{domxref("ResizeObserver.observe()")}}使其寻找特定元素大小的更改。 每次更改大小时,构造函数中设置的回调函数便会运行,从而提供对新维度的访问权限,并允许您根据需要执行任何操作。</p>
<h2 id="接口">接口</h2>
<dl>
<dt>{{domxref("ResizeObserver")}}</dt>
<dd>提供注册新观察者以及启动和停止观察元素的能力。</dd>
<dt>{{domxref("ResizeObserverEntry")}}</dt>
<dd>描述已调整大小的单个元素,标识该元素及其新大小。</dd>
</dl>
<h2 id="例子">例子</h2>
<p>您可以在我们的GitHub存储库中找到几个简单的示例:</p>
<ul>
<li><a href="https://mdn.github.io/dom-examples/resize-observer/resize-observer-border-radius.html">resize-observer-border-radius.html</a> (<a href="https://github.com/mdn/dom-examples/blob/master/resize-observer/resize-observer-border-radius.html">源码</a>): 一个带有绿色框的简单示例,其大小为视口大小的百分比。更改视口大小时,框的圆角将根据框的大小成比例地变化。 我们可以通过 {{cssxref("border-radius")}} 来百分比来实现,但这很快会导致椭圆形的角看起来很丑陋,而上述解决方案为您提供了随盒子大小缩放的漂亮的角形正方形。</li>
<li><a href="https://mdn.github.io/dom-examples/resize-observer/resize-observer-text.html">resize-observer-text.html</a> (<a href="https://github.com/mdn/dom-examples/blob/master/resize-observer/resize-observer-text.html">源码</a>): 这里我们使用resize observer来改变 {{cssxref("font-size")}} ,标题和段落的值随着滑块值的改变而改变,导致包含的<div>改变宽度。 这表明您可以响应元素大小的更改,即使它们与视口无关。</li>
</ul>
<p>代码通常将遵循这种模式 (取自 resize-observer-border-radius.html):</p>
<pre class="brush: js notranslate">const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
if(entry.contentBoxSize) {
entry.target.style.borderRadius = Math.min(100, (entry.contentBoxSize.inlineSize/10) +
(entry.contentBoxSize.blockSize/10)) + 'px';
} else {
entry.target.style.borderRadius = Math.min(100, (entry.contentRect.width/10) +
(entry.contentRect.height/10)) + 'px';
}
}
});
resizeObserver.observe(document.querySelector('div'));</pre>
<h2 id="技术规范">技术规范</h2>
<table>
<tbody>
<tr>
<th scope="col">规范</th>
<th scope="col">状态</th>
<th scope="col">评论</th>
</tr>
<tr>
<td>{{SpecName('Resize Observer')}}</td>
<td>{{Spec2('Resize Observer')}}</td>
<td>Initial definition.</td>
</tr>
</tbody>
</table>
<h2 id="浏览器支持情况">浏览器支持情况</h2>
<p>此页面中的兼容性表是根据结构化数据生成的。如果你想贡献数据,请到 <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> 提PR。</p>
<p>{{Compat("api.ResizeObserver")}}</p>
<h2 id="相关链接">相关链接</h2>
<ul>
<li><a href="https://developers.google.com/web/updates/2016/10/resizeobserver">ResizeObserver: It’s Like document.onresize for Elements</a></li>
</ul>
<ul>
<li></li>
</ul>
|