ResizeObserver处理容器尺寸变化
来源:17golang原创
时间:2026-11-15 17:32:58 282浏览 收藏
ResizeObserver用于观察元素尺寸变化。当侧栏展开、网格列调整或父布局改变组件宽度时,即使浏览器窗口没有变化,也能收到对应元素的尺寸通知。常见写法是创建观察器、observe目标元素,在回调中读取entry的尺寸,并在组件销毁时disconnect。
规范入口:https://drafts.csswg.org/resize-observer/
理解元素尺寸观测能力
这个能力把响应条件从“窗口大小”推进到“元素大小”,适用于依赖容器实际空间的图表、编辑区和自定义组件。这里按生态能力解读与快速试用展开,不将成熟API包装为刚发布的新闻,也不声称做过浏览器实测。
若只是改变CSS样式,优先评估容器查询等CSS方案;当需要调用组件自身的布局接口、更新JavaScript状态或重排内部业务视图时,再考虑ResizeObserver。它不是检测元素进入视口的IntersectionObserver,也不负责告诉你DOM属性具体改了什么。
选择容器与测量口径
示例观察外层host,用它的content-box物理宽度决定内部content是否隐藏辅助说明。父布局负责外层宽度,脚本只切换内部展示,尽量避免“根据刚测出的宽度再修改同一容器宽度”的反馈。

本文读取entry.contentRect.width,与observe的content-box口径对应。边框盒应选择border-box及对应字段;inlineSize属于逻辑轴尺寸,不应无条件当作物理宽度。遇到竖排或碎片布局,需先明确组件真正需要哪一种尺寸。
实现尺寸读取与合并更新
将下面HTML、CSS和JavaScript放入自己的页面,在DOM创建后挂载。代码是本次原创说明示例,未在本机运行。
今日处理量 (按当前筛选条件统计)
/* 父布局需要允许此项收缩;本例不修改被观测容器的宽度。 */
.metric-host { width: 100%; min-width: 0; }
#metric-content { overflow-wrap: anywhere; }
#metric-content[data-mode="compact"] .detail { display: none; }function mountContainerMode(host, content) {
if (!(host instanceof Element) || !(content instanceof Element)) {
throw new TypeError("需要容器及内容元素");
}
if (!("ResizeObserver" in window)) {
// 保留默认展示;旧环境的策略由调用方明确选择。
return () => {};
}
let frame = null;
let latestWidth = 0;
let destroyed = false;
const previousMode = content.getAttribute("data-mode");
const observer = new ResizeObserver(entries => {
for (const entry of entries) {
if (entry.target !== host) continue;
// 本例使用content-box物理宽度,不混入border-box或逻辑轴尺寸。
latestWidth = entry.contentRect.width;
if (frame !== null) continue;
frame = requestAnimationFrame(() => {
frame = null;
if (destroyed) return;
const mode = latestWidth 回调可能收到多个entry,因此按target选择本例容器。latestWidth保存最近一次通知,requestAnimationFrame只保留一个待执行更新;data-mode没有变化时不重复写入。460像素是演示阈值,应按内容长度和设计要求选择。
这里的合并更新是应用层安排,并不意味着已经测得性能提升。若要评估收益,应在相同布局操作下比较回调耗时、写入次数和长任务情况,不用臆造的帧率数字代替测量。
对比旧方案与采用方式
| 方案 | 适合条件 | 边界 |
|---|---|---|
| window.resize | 关注视口变化 | 不能覆盖所有仅由容器内部布局引起的变化 |
| 定时读取尺寸 | 特殊兼容场景 | 有重复读取与时延,需要自行管理生命周期 |
| ResizeObserver | JavaScript需要知道元素尺寸 | 回调更新仍需避免反向改变观测尺寸 |
| CSS容器查询 | 主要是样式响应 | 不能替代任意JavaScript业务处理 |
尝试时不必拖动整个窗口,可以在现有页面折叠侧栏、改变父网格分配,再观察内部辅助说明是否切换。应检查控制权是否明确:若框架也在写同一个data-mode,改为由框架状态统一驱动,避免两套机制争用属性。
不支持ResizeObserver时,本例保留原始展示。实际产品可以选择CSS替代、经过评估的polyfill或明确降级提示,但不应把只监听window.resize宣称为完全等价兼容。
处理反馈循环和生命周期

requestAnimationFrame不会自动消除逻辑循环。如果内部样式改变又导致父容器宽度改变,并使模式在阈值两侧来回切换,即使每次放到下一帧仍可能震荡。应修正布局依赖,让外层宽度由独立父布局决定;确有临界抖动时,可设计进入与退出不同的阈值,但不能用它掩盖无限扩张的规则。
规范包含对未能在当前通知轮次交付的观测的处理及循环错误报告。看到“ResizeObserver loop completed with undelivered notifications.”时,应查回调里的尺寸写入链,而不是全局屏蔽错误信息。
组件卸载前调用dispose,停止观测并取消待写帧。只移除DOM节点不应当作完整清理方案;若仍保留观察器与闭包引用,生命周期责任并未明确完成。本例销毁函数可重复调用,并恢复此前的data-mode,前提是该属性始终由它独占管理。
速查与相关问题
| 事项 | 本文做法 |
|---|---|
| 测量对象 | 外层host |
| 盒模型 | content-box |
| 宽度字段 | contentRect.width |
| 写入目标 | 内部content的data-mode |
| 更新安排 | 合并到一个requestAnimationFrame |
| 销毁 | disconnect与cancelAnimationFrame |
为什么缩放transform没有通知?
CSS transform本身不触发这里所观察的布局尺寸变化。若需求是屏幕上的变换后几何,应另行明确测量方式,不要把两种大小混为一谈。
隐藏容器的尺寸能直接用于重排吗?
不要假定隐藏时仍具有可用宽度。可以在回调中按业务约定处理零尺寸,并在重新显示后根据有效通知更新。也不要只等待窗口resize恢复布局。
一个观察器能监听多个容器吗?
可以多次observe,回调按entry.target分发。此时需为每个目标分别维护状态与待写任务;本文函数刻意只负责一个容器。
-
130 收藏
-
414 收藏
-
163 收藏
-
137 收藏
-
160 收藏
-
177 收藏
-
文章 · 前端 | 34分钟前 | 前端开发 · 浏览器API · CSS View Transition API view-transition-name view-transition-class 伪元素动画413 收藏
-
文章 · 前端 | 37分钟前 | javascript · 前端开发 · 浏览器API · Shadow DOM adoptedStyleSheets CSSStyleSheet replaceSync Constructable Stylesheets500 收藏
-
326 收藏
-
461 收藏
-
文章 · 前端 | 16小时前 | javascript · web安全 · 前端开发 · 浏览器API · writeText Permissions Policy Clipboard API clipboard-write 安全上下文 用户激活390 收藏
-
文章 · 前端 | 16小时前 | html · javascript · 前端开发 · 可访问性 · 浏览器API · JavaScript 模态对话框 ::backdrop HTML dialog showModal inert top layer160 收藏
-
文章 · 前端 | 16小时前 | javascript · 前端开发 · 浏览器API · @import Shadow DOM CSSStyleSheet replaceSync Constructable Stylesheets333 收藏
-
348 收藏
-
文章 · 前端 | 16小时前 | RTCDataChannel bufferedAmount bufferedAmountLowThreshold bufferedamountlow WebRTC背压471 收藏
-
253 收藏
-
172 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习