基础用法
- 创建 ResizeObserver 实例:通过构造函数创建一个观察器,并传入一个回调函数。该回调函数会在元素尺寸变化时执行。
- 指定要观察的元素:使用
observe()
方法开始观察指定的元素。 - 停止观察:可以使用
unobserve()
方法停止观察特定元素,或使用disconnect()
方法停止观察所有元素。
语法:
const resizeObserver = new ResizeObserver(callback);
其中,callback
是一个函数,它接收两个参数:
entries
:一个ResizeObserverEntry
对象的数组,每个对象代表一个被观察元素的尺寸变化信息。observer
:对ResizeObserver
实例本身的引用。
ResizeObserverEntry 对象:
每个 ResizeObserverEntry
对象包含以下属性:
属性 | 描述 |
---|---|
target |
被观察的元素。 |
contentRect |
一个 DOMRectReadOnly 对象,包含元素内容区域的尺寸和位置信息(width, height, top, right, bottom, left, x, y)。 |
borderBoxSize |
一个数组(为了支持多片段布局,如多列),包含一个对象,该对象有 blockSize (垂直方向尺寸,相当于高度)和 inlineSize (水平方向尺寸,相当于宽度)属性。注意:在部分浏览器中可能不是数组。 |
contentBoxSize |
同上,但描述内容区域。 |
devicePixelContentBoxSize |
同上,但尺寸以设备像素为单位。 |
注意:borderBoxSize
、contentBoxSize
和 devicePixelContentBoxSize
是较新的属性,可能在一些浏览器中不支持。
示例代码
// 创建观察器实例
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
// 使用 contentRect
console.log('元素高度:', entry.contentRect.height);
console.log('元素宽度:', entry.contentRect.width);
// 或者使用 borderBoxSize(注意:可能是一个数组)
if (entry.borderBoxSize) {
// 标准方式:borderBoxSize 是一个数组(处理多片段情况,通常只有一个元素)
const borderBoxSize = Array.isArray(entry.borderBoxSize) ? entry.borderBoxSize[0] : entry.borderBoxSize;
console.log('borderBox 高度:', borderBoxSize.blockSize);
console.log('borderBox 宽度:', borderBoxSize.inlineSize);
}
// 同样,contentBoxSize 也是数组
if (entry.contentBoxSize) {
const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;
console.log('contentBox 高度:', contentBoxSize.blockSize);
console.log('contentBox 宽度:', contentBoxSize.inlineSize);
}
}
});
// 选择要观察的元素
const element = document.getElementById('myElement');
// 开始观察元素
resizeObserver.observe(element);
// 如果需要停止观察单个元素
// resizeObserver.unobserve(element);
// 停止观察所有元素
// resizeObserver.disconnect();
框架示例
React 示例(使用钩子):
import { useEffect, useRef } from 'react';
function ResizeObserverComponent() {
const elementRef = useRef(null);
useEffect(() => {
const element = elementRef.current;
if (!element) return;
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
console.log('尺寸变化:', entry.contentRect);
}
});
resizeObserver.observe(element);
// 清理函数
return () => {
resizeObserver.disconnect();
};
}, []);
return <div ref={elementRef}>监听我的尺寸变化</div>;
}
Vue 示例(组合式 API):
<template>
<div ref="targetElement">监听我的尺寸变化</div>
</template>
<script>
import { ref, onMounted, onBeforeUnmount } from 'vue';
export default {
setup() {
const targetElement = ref(null);
onMounted(() => {
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
console.log('尺寸变化:', entry.contentRect);
}
});
resizeObserver.observe(targetElement.value);
// 组件卸载前停止监听
onBeforeUnmount(() => {
resizeObserver.disconnect();
});
});
return { targetElement };
}
};
</script>