ResizeObserver
用于观察元素内容或边框的尺寸变化。
在这个 API 之前,都是通过 window 的 resize
事件监听元素的尺寸变化。但是这种方法不适用于这种场合:
- 浏览器窗口大小没有变化但是元素的大小改变了的情况,比如添加删除元素隐藏元素,以及动态改变元素的大小。
- 浏览器窗口尺寸改变了,但是元素的尺寸并没有变化,此时
resize
事件就浪费了。ResizeObserver
对这种场景下的使用提供了支持,而且可以替代常规的resize
事件监听器,由于ResizeObserver
避免了事件捕获/泡泡的开销,在性能上也会更好。
使用
从名字上看,ResizeObserver
采用了观察者模式,观察者模式在前端是一个很常用的设计模式,不再详细介绍
。使用起来也很简单:
// 创建一个观察者对象 |
ResizeObserverEntry 对象
传递给 ResizeObserver
构造器回调函数 callback
中的参数是 ResizeObserverEntry 对象的集合。它有两个属性 contentRect
和 target
。来看一下 ResizeObserverEntry 结构:
const observer = new ResizeObserver(entries => { |
可以看到输出:
接口定义
下面列出了 ResizeObserver
的详细定义:
interface ResizeObserver { |
触发条件
W3C 规范指定了 ResizeObserver
的触发条件:
- 当被观察的元素从 DOM 中插入或移除时,将会触发;
- 当被观察的元素可见或不可见时,也会触发,比如 display 属性改变为 none 或者取消 none;
以下条件下不会触发:
- 内联元素不会触发;
- CSS transform 也不会触发;
一些使用场景总结
适用于替代原来的 onresize 事件
比如监听 textarea 大小的改变:
const initContentRect = null; |
感知元素的可见性
元素的 display 属性改变也会触发 ResizeObserver
的可见性,因此也可以被用来感知元素是否被使用 display: none
隐藏。
const observer = new ResizeObserver(function(entries) { |
兼容性
接下来看一下浏览器兼容性:
从上面可以看出来,浏览器兼容性支持度还可以,而且还有基于 MutationObserver API 实现的 polyfill 。