推荐答案
Resize Observer API 用于监听 HTML 元素的尺寸变化。当元素的大小(包括内容盒、内边距盒、边框盒)发生变化时,它会异步地通知观察者。这使得我们能够响应元素的尺寸变化,从而进行布局调整、动态计算等操作,而且不会像使用 window.onresize 那样触发频繁的回流和重绘。
使用 ResizeObserver 的基本步骤如下:
创建
ResizeObserver实例:const resizeObserver = new ResizeObserver(entries => { // 响应尺寸变化的回调函数 entries.forEach(entry => { // entry 包含观察到的元素及其新的尺寸信息 console.log(entry.target, entry.contentRect); // 执行你需要的操作 }); });回调函数接收一个
entries数组,其中每个entry都是一个ResizeObserverEntry对象,包含了观察到的元素和它的尺寸信息。使用
observe()方法开始观察元素:const element = document.getElementById('my-element'); resizeObserver.observe(element);这将开始观察
element的尺寸变化。使用
unobserve()方法停止观察单个元素,或使用disconnect()方法停止观察所有元素:// 停止观察单个元素 resizeObserver.unobserve(element); // 停止观察所有元素 resizeObserver.disconnect();
本题详细解读
Resize Observer API 的作用
ResizeObserver 提供了一种高效且规范的方式来监听元素的尺寸变化。它解决了传统方式(如 window.onresize 和轮询)的不足:
- 效率高:
ResizeObserver只在元素实际尺寸发生变化时才触发回调,避免了不必要的计算和性能开销。 - 精确: 能够准确地获取元素的内容盒子、内边距盒子和边框盒子的大小,提供了更精细的控制。
- 针对元素而非窗口:
window.onresize监听的是整个窗口的尺寸变化,而ResizeObserver可以针对单个元素进行监听,更灵活。 - 异步: 回调函数会在浏览器布局和绘制完成后异步执行,避免了在布局计算期间修改 DOM 而导致的布局抖动问题。
ResizeObserver 的用法详解
1. 创建 ResizeObserver 实例
使用 new ResizeObserver(callback) 来创建一个 ResizeObserver 实例,其中 callback 是一个回调函数,会在元素尺寸发生变化时被触发。回调函数会接收一个 entries 数组作为参数,该数组包含一个或多个 ResizeObserverEntry 对象,每个对象都包含了一个被观察的元素及其最新的尺寸信息。
// www.javascriptcn.com code example
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
//处理每个 entry
console.log(entry.target); // 被观察的元素
console.log(entry.contentRect); // 元素的内容盒子大小
console.log(entry.borderBoxSize); //元素的边框盒子大小(仅在支持的浏览器中)
console.log(entry.devicePixelContentBoxSize); //元素的内容盒子大小,以设备像素表示(仅在支持的浏览器中)
}
});2. 观察元素
使用 observe(element) 方法来开始观察特定元素的尺寸变化。
const myElement = document.getElementById('my-element');
resizeObserver.observe(myElement);可以在同一ResizeObserver实例上多次调用observe以监听多个元素。
3. 取消观察
使用 unobserve(element) 方法来停止观察某个特定的元素,或使用 disconnect() 方法来停止观察所有元素。
//停止观察单个元素 resizeObserver.unobserve(myElement); //停止观察所有元素 resizeObserver.disconnect();
4. ResizeObserverEntry 对象
回调函数中接收的 entries 数组中的每个对象都是一个 ResizeObserverEntry 实例,该实例提供了以下属性:
target: 被观察的元素。contentRect: 一个DOMRectReadOnly对象,包含了元素内容盒子的尺寸和位置信息。borderBoxSize:一个只读数组,包含了元素的边框盒子大小,数组中每个元素都是一个ResizeObserverSize对象,包括inlineSize和blockSize。仅部分浏览器支持。devicePixelContentBoxSize:一个只读数组,包含了元素的内容盒子大小,以设备像素表示,数组中每个元素都是一个ResizeObserverSize对象,包括inlineSize和blockSize。仅部分浏览器支持。
5. 实际应用
ResizeObserver 常用于以下场景:
- 自适应布局: 根据元素尺寸变化动态调整布局。
- 图表和可视化: 根据容器尺寸变化动态调整图表的绘制。
- 响应式图片: 根据容器尺寸变化动态加载不同大小的图片。
- 自定义组件: 创建可根据自身尺寸动态调整的自定义组件。
6. 注意事项
ResizeObserver是异步的,回调函数会在浏览器布局完成后执行。- 如果在回调函数中修改了 DOM,可能会触发新的布局计算,从而可能导致新的回调执行,需要小心处理,避免无限循环。
- 并非所有浏览器都完全支持
ResizeObserver的所有特性(如borderBoxSize和devicePixelContentBoxSize),需要考虑兼容性。可以通过 polyfill 来支持老旧浏览器。