无需登录 数据私有 本地保存

ResizeObserver演示 - 响应元素尺寸变化

11
0
0
0

ResizeObserver 演示

实时监听元素尺寸变化 · 支持手动拖拽 & 内容驱动 · 完整展示 contentRect / borderBoxSize

ResizeObserver API 实时监听
演示元素 A 拖拽调整 滑块控制 拖拽右下角或使用下方控件改变大小
340 × 240
拖拽 ⤡ 改变大小
拖拽调整
演示元素 B 内容驱动 输入文字,元素高度自动扩展
这里输入内容,当文字增多时,元素高度会自动扩展。ResizeObserver 会检测到每一次尺寸变化。
当前: --
实时数据 观察中
当前宽度
340
px
当前高度
240
px
contentRect
width: 316px height: 192px
borderBoxSize
inlineSize: 340px blockSize: 240px
变化次数: 0 box-sizing: border-box
当前宽度
--
px
当前高度
--
px
contentRect
width: --px height: --px
borderBoxSize
inlineSize: --px blockSize: --px
变化次数: 0 contenteditable
变化日志 0 条记录
等待元素尺寸变化...
拖拽元素右下角、拖动滑块,或在元素B中输入文字
常见问题 & 知识点

ResizeObserver 是一个现代浏览器API,用于监听DOM元素的尺寸变化。与传统的 window.resize 事件不同,ResizeObserver 可以精确监听任意元素(而不仅是视口)的尺寸变化,包括由CSS、内容变化、JavaScript动态修改等引起的尺寸改变。

核心优势:它是浏览器原生支持的、高性能的尺寸监听方案,不需要使用 setInterval 轮询或复杂的MutationObserver组合,避免性能浪费。

特性window.resizeResizeObserver
监听范围仅视口(viewport)任意DOM元素
触发精度视口变化时元素实际尺寸变化时(包括内容驱动)
性能需要手动防抖浏览器原生优化,自动批量处理
使用场景响应式布局组件尺寸监听、Canvas自适应、动态布局等
检测内容变化❌ 不支持✅ 支持(如contenteditable元素扩展)

  • contentRect:返回元素的内容区域尺寸(不含padding、border、滚动条),类型为 DOMRectReadOnly。这是较早的API,兼容性最好。
  • borderBoxSize:返回元素的边框盒尺寸(含padding和border),类型为数组 [{blockSize, inlineSize}]。在水平书写模式下,inlineSize=宽度,blockSize=高度。
  • contentBoxSize:返回内容盒尺寸,与contentRect类似但精度更高(使用double而非float)。
  • devicePixelContentBoxSize:返回设备像素级别的尺寸,考虑设备像素比(DPR),在Retina屏幕上特别有用。

💡 在本工具中,元素A使用 box-sizing: border-box,padding为24px,border为3px,所以 contentRect.width = borderBoxSize.inlineSize - 54px。

  1. 自适应Canvas/SVG:当容器尺寸变化时,自动调整画布分辨率。
  2. 响应式组件:根据组件宽度切换布局(如卡片从横排变为竖排)。
  3. 动态文字大小:根据容器大小调整字体(容器查询的替代方案)。
  4. 聊天窗口自动滚动:检测消息列表高度变化,自动滚动到底部。
  5. 第三方嵌入内容:如广告iframe尺寸变化时调整父容器。
  6. contenteditable编辑器:监听编辑区域随内容增长的高度变化。
  7. 数据可视化:图表容器尺寸变化时重新渲染图表。

  • 批量处理:回调中的 entries 数组可能包含多个元素的变化,需要遍历处理。
  • 及时清理:使用 observer.disconnect()observer.unobserve(element) 停止观察,避免内存泄漏。
  • 避免循环更新:在回调中修改元素大小可能触发新的回调,需要添加条件判断避免无限循环。
  • 异步执行:ResizeObserver 的回调在浏览器布局后异步执行,不会阻塞渲染。
  • 浏览器兼容性:主流浏览器(Chrome 64+、Firefox 69+、Safari 13.1+、Edge 79+)均已支持。
  • 一个Observer可观察多个元素:通过多次调用 observe() 添加多个目标,在回调中通过 entry.target 区分。

当元素设置了 resize: both(需配合 overflow: auto/hidden/scroll),用户可以通过拖拽元素右下角的手柄来改变元素大小。ResizeObserver 会实时检测这些由用户拖拽引起的尺寸变化,就像检测JavaScript修改的大小一样。

这使得开发者可以响应用户手动调整大小的行为,例如:保存用户的面板大小偏好、动态调整内部布局、更新图表等。在本工具中,你可以拖拽元素A的右下角来体验这一点。

ResizeObserver 的设计非常注重性能:

异步回调:尺寸变化通知在浏览器完成布局后异步触发,不会阻塞渲染管道。
批量处理:同一帧内的多个尺寸变化会被合并,回调只触发一次。
零开销空闲:当没有尺寸变化时,不消耗任何CPU资源(与轮询方案不同)。
原生实现:由浏览器引擎直接支持,效率远高于JavaScript模拟方案。

相比使用 setIntervalrequestAnimationFrame 轮询元素尺寸,ResizeObserver 在性能和准确性上都有显著优势。