在前端开发中,监听元素尺寸变化是常见的需求,比如侧边栏折叠后内容区域自适应、图表跟随容器大小调整显示效果等。过去开发者通常会使用window的resize事件配合getBoundingClientRect方法轮询检测,或者用MutationObserver监听元素属性变化间接判断尺寸,但这些方式要么覆盖范围有限,要么性能开销较高。ResizeObserver是浏览器原生提供的专门用于监听元素尺寸变化的API,能够直接监听指定元素的宽高变化,使用起来更加高效便捷。

ResizeObserver基本用法
ResizeObserver的使用流程和MutationObserver类似,主要分为三步:创建观察者实例、定义回调函数、指定要观察的元素。
1. 创建ResizeObserver实例
通过new ResizeObserver()创建实例,构造函数接收一个回调函数,当被观察的元素尺寸发生变化时,这个回调会被触发。
// 创建ResizeObserver实例
const resizeObserver = new ResizeObserver((entries) => {
// entries是所有发生尺寸变化的元素的信息数组
entries.forEach(entry => {
console.log('元素尺寸变化了', entry);
});
});
2. 监听指定元素
使用observe方法指定要监听的元素,可以多次调用该方法监听多个不同的元素。
// 获取要监听的元素
const targetElement = document.querySelector('.content-box');
// 开始监听该元素
resizeObserver.observe(targetElement);
3. 停止监听
当不再需要监听某个元素时,可以调用unobserve方法停止对该元素的监听;如果要停止所有监听,可以调用disconnect方法。
// 停止监听单个元素 resizeObserver.unobserve(targetElement); // 停止所有监听 resizeObserver.disconnect();
回调函数参数详解
ResizeObserver的回调函数接收一个entries数组,数组中的每个元素都是ResizeObserverEntry对象,包含了对应元素的变化信息,常用的属性如下:
| 属性名 | 说明 |
|---|---|
| target | 发生尺寸变化的DOM元素 |
| contentRect | 元素的内容矩形信息,包含x、y、width、height、top、right、bottom、left等属性 |
| borderBoxSize | 元素的边框盒尺寸数组,包含blockSize(块方向尺寸,对应高度)和inlineSize(行内方向尺寸,对应宽度) |
| contentBoxSize | 元素的内容盒尺寸数组,同样包含blockSize和inlineSize |
下面是一个使用回调参数获取元素最新尺寸的例子:
const resizeObserver = new ResizeObserver((entries) => {
entries.forEach(entry => {
const { width, height } = entry.contentRect;
console.log(`元素当前尺寸:宽度${width}px,高度${height}px`);
// 可以在这里处理尺寸变化后的逻辑,比如调整图表大小
});
});
const chartContainer = document.querySelector('#chart-container');
resizeObserver.observe(chartContainer);
常见使用场景
1. 响应式内容自适应
当侧边栏折叠或展开时,右侧内容区域的宽度会发生变化,使用ResizeObserver可以监听内容区域的尺寸变化,动态调整内部组件的布局。
const contentArea = document.querySelector('.main-content');
const resizeObserver = new ResizeObserver((entries) => {
const { width } = entries[0].contentRect;
// 根据宽度调整内部卡片的列数
const cardContainer = contentArea.querySelector('.card-container');
if (width < 768) {
cardContainer.style.gridTemplateColumns = '1fr';
} else if (width < 1200) {
cardContainer.style.gridTemplateColumns = 'repeat(2, 1fr)';
} else {
cardContainer.style.gridTemplateColumns = 'repeat(3, 1fr)';
}
});
resizeObserver.observe(contentArea);
2. 图表自适应容器
很多图表库需要明确容器的尺寸才能正确渲染,当容器尺寸变化时,需要重新渲染图表。使用ResizeObserver可以在容器尺寸变化时触发图表的重新绘制。
// 假设已经初始化了一个echarts实例
const chartDom = document.querySelector('#my-chart');
const myChart = echarts.init(chartDom);
const resizeObserver = new ResizeObserver(() => {
// 容器尺寸变化时重新调整图表大小
myChart.resize();
});
resizeObserver.observe(chartDom);
注意事项
- ResizeObserver的回调是异步执行的,并且会在浏览器下一帧绘制前触发,不会阻塞主线程。
- 如果在回调中修改了被观察元素的尺寸,可能会导致无限循环的回调触发,需要做好逻辑判断避免这种情况。
- 旧版本浏览器可能不支持ResizeObserver,使用前可以通过
'ResizeObserver' in window判断兼容性,不支持的情况下可以降级使用传统的resize事件或者定时器轮询方案。 - 观察SVG元素时,ResizeObserver同样可以生效,获取到的contentRect是SVG元素在页面中的实际渲染尺寸。
兼容性处理示例
如果需要兼容不支持ResizeObserver的浏览器,可以添加降级逻辑:
function createResizeListener(element, callback) {
if ('ResizeObserver' in window) {
const observer = new ResizeObserver((entries) => {
callback(entries[0].contentRect);
});
observer.observe(element);
return {
destroy: () => observer.disconnect()
};
} else {
// 降级方案:监听window的resize事件,结合getBoundingClientRect检测
let lastRect = element.getBoundingClientRect();
const handleResize = () => {
const currentRect = element.getBoundingClientRect();
if (currentRect.width !== lastRect.width || currentRect.height !== lastRect.height) {
callback(currentRect);
lastRect = currentRect;
}
};
window.addEventListener('resize', handleResize);
// 可以额外添加定时器检测,应对非window resize导致的尺寸变化
const timer = setInterval(handleResize, 500);
return {
destroy: () => {
window.removeEventListener('resize', handleResize);
clearInterval(timer);
}
};
}
}
// 使用方式
const target = document.querySelector('.box');
const listener = createResizeListener(target, (rect) => {
console.log('尺寸变化', rect.width, rect.height);
});
// 不需要监听时销毁
// listener.destroy();
ResizeObserver元素尺寸监听JavaScript前端性能优化修改时间:2026-06-09 18:39:22