摘要

  • W3C 于 2020 年 2 月 11 日发表 Resize Observer 首份公开工作草案,提出观察元素自身尺寸变化,并通过回调交付测量记录。
  • CSSWG 编辑草案区分内容盒、边框盒和设备像素内容盒,并规定通知在渲染周期中的交付方式;重复触发而未能交付的变化会得到循环错误通知。

一张仪表盘卡片里放着图表。网页的网格决定卡片能分到多少宽度,图表作者决定坐标轴上写多少字。侧栏打开后,卡片变窄,浏览器窗口却还是原来的尺寸。网页布局不必懂图表里的每一根刻度线,图表也管不了侧栏要占多少地盘。双方需要一条很窄的消息:你现在还有这么宽。

W3C 2020 年 2 月 11 日的首份公开工作草案给出这条消息的接口。ResizeObserver 可以用 observe() 登记目标元素;观察到的盒子尺寸变化时,浏览器把记录交给回调。unobserve() 撤掉一个目标,disconnect() 结束一组观察。W3C 官方发布史确认这份文件的发表日期与首份公开草案身份。观察对象从整扇窗,移到了真正需要腾挪的那件家具上。

图表获得新尺寸后,可以少画几根刻度、调整图例,或者重绘画布。测量由浏览器提供,取舍由图表作者决定。这个分工使网页仍能自由安排侧栏和网格,组件也能根据实际拿到的空间做判断。观察器交来的是尺码,不是设计方案。

尺码还分种类。CSSWG 的 Resize Observer Module Level 1 编辑草案列出 content-box、border-box 和 device-pixel-content-box。第一种看内容区域,第二种包括边框区域,第三种以设备像素报告内容区域,并在 CSS 变换之前计算。文字排版、带框卡片、需要清晰像素的 canvas,各自关心的尺寸不同。选错尺子,后面再聪明的回调也会忙错地方。

observe() 里的盒子选项决定哪一种变化会触发通知;收到的记录还可提供不同的尺寸字段。触发条件与可读取的数据要分别理解。组件从页面撤下后,也该撤销观察,免得装修队已经收工,量尺的人还天天来敲门。

回调里藏着一出闹剧:它发现卡片太窄,于是把卡片放大;新尺寸又让它把卡片缩小;下一次通知继续放大。CSSWG 草案把观察处理放进渲染步骤,并以元素深度限制一轮中重复交付的机会。尚未交付的变化可以触发循环错误通知,随后在下一帧继续处理。组件作者要让调整最终停下来:图表适应分到的空间,别反复改动它自己正在观察的外框。

CSSWG 文本标注为 2022 年 11 月 22 日的编辑草案;W3C 发布史记录 2020 年的首份公开草案。原始文件讲明了机制和文档状态。这段历史的精妙处并不喧哗:浏览器只负责量准一个元素的地方,具体怎样住进去,留给这个元素的作者。