ResizeObserver 监听元素尺寸变化比轮询或 window.resize 更精准高效,支持 content/border box,异步回调不触发重排重绘,需挂载后观察、卸载前清理,现代浏览器原生支持。

当元素尺寸发生变化时,用 ResizeObserver 监听比轮询或绑定 window.resize 更精准、高效,尤其适合动态内容、响应式布局或第三方组件嵌入场景。它能直接响应目标元素的 content box(默认)或 border box 的变化,且不触发重排重绘。
创建并启动 ResizeObserver 实例
先实例化观察器,传入一个回调函数,该函数接收两个参数:变化记录列表(entries)和观察器实例本身。每条记录包含 target(被观察元素)和 contentRect(含 width/height 等尺寸信息)。
- 确保在元素挂载到 DOM 后再开始观察,否则会报错
- 一个观察器可同时观察多个元素,调用
observe(el)多次即可 - 使用
unobserve(el)停止监听单个元素,disconnect()彻底停止所有监听
监听指定 DOM 元素的尺寸变化
选中目标元素后,调用 observe() 即可。注意:ResizeObserver 默认观测 content box,若需 border box,需配合 CSS box-sizing: border-box 并读取 borderBoxSize(需检查浏览器支持)。
const target = document.querySelector('#my-panel');
const ro = new ResizeObserver(entries => {
for (const entry of entries) {
const { width, height } = entry.contentRect;
console.log('尺寸更新:', width, 'x', height);
// 在这里执行适配逻辑,如调整子元素、重绘 Canvas、更新虚拟滚动范围等
}
});
ro.observe(target); // 开始监听
结合 DOM 查询动态绑定多个元素
如果页面有多个同类容器(如卡片、面板、图表容器),可用 document.querySelectorAll 批量获取,再遍历调用 observe:
立即学习“Java免费学习笔记(深入)”;
- 避免重复观察同一元素(可加 Map 缓存已观察的节点)
- 监听前建议检查元素是否存在且已 layout(例如在
DOMContentLoaded或requestAnimationFrame中执行) - 若元素可能被销毁(如 SPA 路由切换),务必在卸载前调用
unobserve或disconnect,防止内存泄漏
常见注意事项与兼容性处理
ResizeObserver 已被 Chrome 64+、Firefox 69+、Safari 13.1+ 和 Edge 79+ 原生支持。旧版浏览器需引入 polyfill(如 juggle/resize-observer)。
- 回调是异步微任务,不会阻塞渲染;但频繁触发时建议防抖(如用
setTimeout合并多次变化) - 不响应 CSS 动画导致的尺寸过渡(只报告最终值),也不响应
display: none切换(此时contentRect为 0) - 若元素父容器隐藏或未渲染,观察将无效——确保元素处于文档流中且可见


















