ResizeObserver 是 W3C 标准中异步监听 DOM 元素 content box 尺寸变化的原生 API,响应及时、性能友好,不触发重排;回调在布局后绘制前批量执行,自动忽略不可见元素,现代浏览器广泛支持,旧环境可降级为 resize + rAF 轮询。

ResizeObserver 是 W3C 标准中用于异步监听 DOM 元素尺寸变化的原生 API,它不依赖重排(reflow)或轮询,响应及时、性能友好,是替代 window.onresize 或手动监听 scroll/resize 事件监听器的最佳实践。
核心行为规范
ResizeObserver 按照以下关键规则运作:
- 仅监听元素的 content box 尺寸变化(即 width/height,不含 padding/border/margin),可通过
box选项扩展为监听border-box或device-pixel-content-box(需浏览器支持) - 回调函数在浏览器完成布局后、绘制前的 resize tasks 阶段 异步触发,保证与渲染节奏一致,避免强制同步布局
- 一次批量通知:当多个被观察元素同时变化时,回调只执行一次,传入包含所有变化记录的数组(
ResizeObserverEntry[]) - 自动忽略不可见元素(如
display: none、visibility: hidden、未插入 DOM 或在iframe中且无 layout 的元素)
基本使用方式
创建实例并观察目标元素:
const ro = new ResizeObserver(entries => {
for (const entry of entries) {
const { contentRect, target } = entry;
console.log('宽:', contentRect.width, '高:', contentRect.height);
}
});
ro.observe(document.getElementById('my-element'));
注意:contentRect 是只读的 DOMRectReadOnly 对象,其 width/height 精确反映内容区尺寸;target 指向被观察的原始元素。
重要限制与注意事项
- 不触发于 CSS 动画/transition 过程中的中间尺寸(仅在最终布局生效后通知)
- 不监听字体加载、图片加载导致的回流(除非该回流实际改变了元素 content box 尺寸)
- 若元素被移出 DOM,会自动停止监听;调用
unobserve(el)或disconnect()可主动清理 - 在 iframe 中使用时,需确保跨域策略允许访问其 document(同源或已配置
document.domain) - 部分旧版 Safari(≤15.4)对
device-pixel-content-box支持不完整,建议降级处理
兼容性与降级建议
现代浏览器(Chrome 64+、Firefox 69+、Safari 13.1+、Edge 79+)均已支持。对于不支持环境,可采用轻量降级方案:
- 监听
window.resize+ 定时检测(如requestAnimationFrame轮询getBoundingClientRect()),仅用于关键容器 - 使用社区维护的 polyfill(如 juggle/resize-observer),但注意其无法完全复现原生的异步时机和精度
- 服务端渲染(SSR)场景下,首次 hydration 前无需监听,应在
useEffect(React)或mounted(Vue)中初始化
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











