ResizeObserver

高效监听元素尺寸变化的现代 API

API 说明

ResizeObserver 提供了一种高效监听元素尺寸变化的方法。相比 window.resize 事件,它可以精确监听单个元素的变化,性能更好。

const observer = new ResizeObserver(entries => {
  for (let entry of entries) {
    console.log('元素尺寸:', entry.contentRect);
    console.log('宽度:', entry.contentRect.width);
    console.log('高度:', entry.contentRect.height);
  }
});

// 开始观察
observer.observe(element);

// 停止观察
observer.unobserve(element);

// 完全停止
observer.disconnect();
  • contentRect - 元素的内容区域矩形(不含 border 和 padding)
  • borderBoxSize - 元素的 border-box 尺寸
  • contentBoxSize - 元素的 content-box 尺寸

💡 优势

ResizeObserver 可以监听任意元素的尺寸变化,不仅仅是窗口。它比轮询检查或使用 MutationObserver 更高效。

示例 1:基础用法

调整元素大小,观察尺寸变化

调整我的大小

实时数据

contentRect.width: 0px
contentRect.height: 0px
变化次数: 0
const observer = new ResizeObserver(entries => {
  for (let entry of entries) {
    const { width, height } = entry.contentRect;
    console.log(`新尺寸: ${width} × ${height}`);
  }
});

observer.observe(document.getElementById('box'));

示例 2:响应式组件

根据容器尺寸自动调整布局

响应式组件

当前布局: -

容器宽度: -

💡 实际应用

这是响应式组件的基础。你可以根据容器宽度切换不同的布局模式,实现真正的响应式设计,而不仅仅是依赖媒体查询。

示例 3:监听多个元素

同时观察多个元素的尺寸变化

元素 A
元素 B
元素 C

变化日志

等待尺寸变化...

// 观察多个元素
const observer = new ResizeObserver(entries => {
  entries.forEach(entry => {
    console.log(`${entry.target.id}:`, entry.contentRect);
  });
});

[el1, el2, el3].forEach(el => observer.observe(el));

示例 4:性能优化(throttle)

在回调中使用 throttle 避免过于频繁的更新

快速调整大小

性能统计

实际触发次数: 0
throttle 后执行: 0
优化率: 0%

⚠️ 注意

虽然ResizeObserver本身已经经过优化,但在回调中执行复杂操作时,仍建议使用 throttle 或 debounce 来提升性能。

浏览器兼容性

API Chrome Firefox Safari Edge
ResizeObserver ✓ 64+ ✓ 69+ ✓ 13.1+ ✓ 79+
borderBoxSize ✓ 84+ 部分支持 ✓ 84+

💡 Polyfill

对于不支持的浏览器,可以使用 ResizeObserver polyfill

总结

  • 精确监听:可以监听任意元素的尺寸变化
  • 高性能:相比轮询或其他方法,性能更好
  • 内容区域:contentRect 返回元素的 content-box 尺寸
  • 常用场景:响应式组件、自适应布局、Canvas 重绘等
  • 注意事项:避免在回调中触发新的尺寸变化,防止无限循环