ResizeObserver 是监听组件尺寸变化的最优方案,它直接绑定元素、精准触发回调、避免全局事件冲突,支持 iframe 和阴影 DOM,且提供 contentRect 数据;相比 window.resize,它能感知布局重排等细粒度变化。

组件适配不同屏幕尺寸,核心是感知自身尺寸变化并动态调整渲染或行为。ResizeObserver 是浏览器原生提供的轻量、高效方案,它能监听元素内容区或边框区的尺寸变动,无需轮询或依赖窗口 resize 事件,特别适合封装可复用的响应式组件。
为什么用 ResizeObserver 而不是 window.resize?
窗口 resize 事件只反映视口变化,无法感知组件在布局中被拉伸、折叠、拖拽或通过 CSS Grid/Flex 动态重排导致的尺寸变更。而 ResizeObserver 直接绑定到目标元素,只要其盒模型(content-box 或 border-box)尺寸变化就会触发回调,粒度更细、性能更好、语义更准确。
- 不依赖全局事件,避免多组件监听 window.resize 时的冲突与冗余计算
- 自动处理 iframe、阴影 DOM、display: none 元素的边界情况
- 回调中获取的是精确的 contentRect(含 width/height/x/y),无需手动 getBoundingClientRect()
基础用法:监听单个组件容器
在组件挂载后创建 observer,监听根容器,并在卸载前断开连接。以 React 函数组件为例:
useEffect(() => {
const ref = containerRef.current;
if (!ref) return;
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
const { width, height } = entry.contentRect;
// 根据宽高判断断点,例如:窄屏 → 切换为垂直布局
if (width observer.disconnect();
}, []);
进阶技巧:节流响应 + 多尺寸策略
高频尺寸变化(如拖拽调整面板)可能触发密集回调,建议简单节流;同时可结合 aspectRatio、min-width 等逻辑做更精细适配:
- 用 requestAnimationFrame 包裹更新,避免重复 setState
- 缓存上一次处理的尺寸,跳过微小变化(如 ±2px)
- 根据 width/height 比值决定是否启用“横屏模式”或“画布缩放”
- 配合 CSS 定义 @container 查询(需开启 container-type)实现样式层联动
兼容性与降级方案
ResizeObserver 在现代浏览器中已广泛支持(Chrome 64+、Firefox 69+、Safari 13.1+)。对于旧环境,可用 polyfill(如 juggle/resize-observer),或退回到监听 window.resize + 定时检测元素 offsetWidth 变化(仅作兜底,不推荐长期使用)。










