resizeobserver 是浏览器原生监听元素尺寸变化的 api,能响应 flex/grid、字体加载等引发的重排,而 window.onresize 仅监听窗口大小变化。

ResizeObserver 是什么,为什么不能用 window.onresize 替代
ResizeObserver 是浏览器原生的、专门监听元素尺寸变化的 API,它能响应 width、height、border-box 等盒模型变化,包括由 CSS Flex/Grid、display 切换、字体加载、甚至 transform(部分场景)引发的重排。而 window.onresize 只响应窗口大小变化,对内部元素“一无所知”——比如一个 div 因父容器 flex 增长而变宽,window.onresize 完全不会触发。
常见错误现象:
– 手动轮询 getBoundingClientRect(),CPU 占用高、抖动明显;
– 监听 DOMContentLoaded 或 load 后只测一次,漏掉后续动态变化;
– 用 MutationObserver 监听 class 变化“间接推断”尺寸,逻辑脆弱、覆盖不全。
怎么创建并正确使用 ResizeObserver 实例
必须在目标元素存在且已挂载 DOM 后再实例化,否则会静默失败(不报错但不回调)。观察器本身是异步执行的,回调中拿到的尺寸已是稳定后的最新值,无需额外 setTimeout 或 requestAnimationFrame 延迟。
- 用
new ResizeObserver(callback)创建,callback接收两个参数:entries(ResizeObserverEntry数组)和observer(当前实例) - 每个
entry的target是被观察元素,contentRect提供width/height/top/left等,注意它基于content-box,不含 padding/border - 必须显式调用
observer.observe(element)开始监听;若元素销毁,应调用observer.unobserve(element)或observer.disconnect()避免内存泄漏
const ro = new ResizeObserver(entries => {
for (const entry of entries) {
const { width, height } = entry.contentRect;
console.log('尺寸变了:', width, 'x', height);
}
});
ro.observe(document.querySelector('#my-panel'));
哪些尺寸变化它能捕获,哪些不能
它能捕获所有触发 layout(重排)的尺寸变更,但有明确边界:
- ✅ 捕获:
flex分配导致的宽高变化、max-width生效、visibility: hidden→visible、字体加载完成后的回流、resize(仅当元素设了resize: both且用户拖拽) - ❌ 不捕获:
transform(纯绘制层变化,不触发布局)、opacity、filter、will-change、display: none(此时元素脱离文档流,unobserve更合适) - ⚠️ 注意:
box-sizing: border-box下,contentRect仍只反映 content 区域;如需含 padding,要手动加getComputedStyle(target).paddingLeft等
兼容性与降级方案怎么写才不翻车
Chrome 64+、Firefox 69+、Safari 13.1+ 支持,Edge 79+(即 Chromium 内核后全支持)。IE 完全不支持,且无 polyfill 能 100% 模拟——因为底层依赖 layout 触发机制,JS 无法精确模拟。
安全的降级方式只有两种:
- 功能渐进增强:核心逻辑不依赖尺寸监听,仅用 ResizeObserver 做“锦上添花”,比如自动调整图表 canvas 大小,降级时保持静态尺寸
- 轻量轮询兜底(仅限低频场景):
setInterval(() => { if (el && el.offsetWidth !== lastW) { /* 处理 */ } }, 250),务必加clearInterval清理,且避免在动画帧中高频运行
别试图用 IntersectionObserver 或 scroll 事件模拟——它们和尺寸无关,逻辑错位,后期维护成本爆炸。
真正容易被忽略的是:ResizeObserver 回调可能被节流(尤其连续快速 resize 时),但它保证至少触发一次最终状态;如果你需要“每一帧都响应”,说明设计有问题——应该用 CSS 或 requestAnimationFrame 配合 getBoundingClientRect,而不是强求 ResizeObserver。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











