ResizeObserver 的介绍
这个 pollyfill 是用来提供监测目标元素或者页面刷新的一种观察者工具。当目标元素的 clientwidth/height,offsetWidth/Height, 发生变化,或者页面上有动画或者窗体 resize,都会促发回调函数通知观察者。介绍几个类
- ResizeObserver 这个是用来定义观察者的,观察者其实就是一个回调函数,
callback(entris:ResizeObserverEntry[],observer:ResizeObserver)
。 这个观察者有三个方法,observe,unobserve,disconnect。一个 observer 可以同时观察多个 html 元素,它们对应同一个回调函数。- observe, 就是开始观察某个元素,用法 observe(htmlelement).
- unobserve,就是停止观察某个元素,用法 unobserve(htmlelement).
- disconnect,就是停止观察所有的元素.
- ResizeObserverController, 这个是个单例的控制器或者叫调度器。所有的 resizeObserver 归它管理,或者说 ResizeObserverSPI 归它管。它是调度器,它会检测 DOM 上面的变化,通过MutationObserver或者DOMSubtreeModified事件(如果前者不支持的话), 同时它还订阅了transactionend 事件,它只关心这些 css 属性的变化。
const transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];
当这些事件被促发的时候,它就会迭代内部的SPI数组,调用它们的- gatherActive()
- hasActive()
过滤出变化的SPI,
然后对于迭代变化的SPI,依次调用它们的 broadcastActive() 方法。
- ResizeObserverSPI, 这个是真正提供观察某个元素功能的地方,SPI 应该是 service provider interface.的简称。它是ResizeObserver那三个接口真正提供功能的地方。它提供了如下的方法
- observe(htmlelement), 开始观察某个 html 元素,该元素以 ResizeObservation 的形态保存于内部的一个 Map 里面。
- unobserve(htmlelement), 停止观察某个 html 元素
- disconnect() 停止观察所有的 html 元素。
- gatherActive() 轮询内部的 ResizeObservation Map,调用它的 isActive() 方法,发现更新了元素,存放于内部的 activeObservations 数组中
- boradcastActive() 轮询内部的 ResizeObservation Map,调用它的 broadcastRect(),更新最新值。同时调用 callback 通知观察者更新。
- hasActive() 返回当前是否存在更新的元素。
- clearActive() 清除更新的元素数组。activeObservations。
- ResizeObservation 这个类是被观察的元素的封装, 它会保存元素上一次的宽高信息,提供了两个方法
- isActive() 与元素之前的宽高进行比较,如果不同则返回 true,这样就指定这个元素更新了。
- broadcastRect() 这个是用当前的值更新上一次的值。
总结一下,对于我们用户,一般用法就是
- 首先定义 observer,
const callback(param:ResizeObserverEntry[],observer:ResizeObserver)=>{};
const observer = new ResizeObserver(callback);
//然后开始观察某个元素
observer.observe(divelement);
//通知观察
observer.unobserve(divelement);