Resize Observer使用

更新于 阅读 11
Resize Observer使用

Resize Observer是一个新的JavaScript API,与Intersection Observer APIMutation Observer等其他观察者API非常相似。 它允许在尺寸发生变化时通知元素。

基本用法


使用Resize Observer非常简单,只需实例化一个新的ResizeObserver对象并传入一个回调函数,该函数接收观察到的条目

const myObserver = new ResizeObserver(entries => { // iterate over the entries, do something. });

然后,我们可以在实例上调用observe并传入一个元素来观察

const someEl = document.querySelector('.some-element'); const someOtherEl = document.querySelector('.some-other-element'); myObserver.observe(someEl); myObserver.observe(someOtherEl);

对于每个entry,我们都会得到一个包含contentRect和一个target属性的对象。target是DOM元素本身,contentRect是具有以下属性的对象:width,height,x,y,top,right,bottom和left。

与元素的getBoundingClientRect不同,contentRectwidthheight值不包含paddingcontentRect.top是元素的顶部padding,contentRect.left是元素的左侧padding

比如要打印出被监听元素寸尺变化时widthheight的值,可以像下面这样做:

const myObserver = new ResizeObserver(entries => { entries.forEach(entry => { console.log('width', entry.contentRect.width); console.log('height', entry.contentRect.height); }); }); const someEl = document.querySelector('.some-element'); myObserver.observe(someEl);

示例

下面是一个简单的演示,以查看Resize Observer API的实际应用。 通过调整浏览器窗口的大小来尝试一下,注意渐变角度和文本内容仅在元素的大小受到影响时才发生变化:

让我们来分解这个简单的演示。首先,我们从一些简单的标记开始:

<div class="box"> <h3 class="info"></h3> </div> <div class="box small"> <h3 class="info"></h3> </div>

样式:

.box { text-align: center; height: 20vh; border-radius: 8px; box-shadow: 0 0 4px var(--subtle); display: flex; justify-content: center; align-items: center; } .box h3 { color: #fff; margin: 0; font-size: 5vmin; text-shadow: 0 0 10px rgba(0,0,0,0.4); } .box.small { max-width: 550px; margin: 1rem auto; }

请注意,我们不需要将渐变背景应用于.box元素。 当页面第一次加载时,resize观察者将被调用一次,然后我们将应用我们的渐变。 现在,当我们添加下面的JavaScript代码时,就会发生奇迹了:

const boxes = document.querySelectorAll('.box'); const myObserver = new ResizeObserver(entries => { for (let entry of entries) { const infoEl = entry.target.querySelector('.info'); const width = Math.floor(entry.contentRect.width); const height = Math.floor(entry.contentRect.height); const angle = Math.floor(width / 360 * 100); const gradient = `linear-gradient(${ angle }deg, rgba(0,143,104,1) 50%, rgba(250,224,66,1) 50%)`; entry.target.style.background = gradient; infoEl.innerText = `I'm ${ width }px and ${ height }px tall`; } }); boxes.forEach(box => { myObserver.observe(box); });

在这里,我们使用for ... of循环遍历观察者回调中的条目,但在条目上调用forEach将工作得一样。 请注意,我们还必须迭代可以观察的元素,并调用每个元素的观察值。

浏览器支持

浏览器支持现在非常糟糕,只有Chrome 64+支持Resize Observer开箱即用。 谢天谢地,我们可以同时使用polyfill。 该polyfill基于MutationObserver API。

参考文章