# ResizeObserver监听元素的resize事件
最近在写业务中有遇到需要监听一个元素的
resize
事件的需求(为了实现自适应布局)。虽然存在
window.onresize
这个API,但是它却是用来监听浏览器窗口的resize
事件,那我在业务中总不能让用户去拖拽浏览器窗口吧,这听着就不是一个好主意。
几经查找(
百度),发现了ResizeObserver
,虽然该API目前还处在实验中,但是浏览器兼容性非常不错:👇有鉴于我司产品只应用于PC端浏览器,不用考虑兼容移动端,而且貌似也没有其它的解决办法,所以姑且用它把。。
ResizeObserver
的API:👇
方法 | 介绍 |
---|---|
ResizeObserver.disconnct() | 取消和结束目标对象上所有对Element 或SVGElement 观察。 |
ResizeObserver.observe() | 开始观察指定的Element 或SVGElement 。 |
ResizeObserver.unobserve() | 结束观察指定的Element 或SVGElement 。 |
# 一、使用
# 创建一个ResizeObserver
const ro = new ResizeObserver(res => {
console.log(res);// 看一下返回的东西
})
ro.observe(document.getElementById("xxx"));
2
3
4
5
返回的是一个数组,它里面最重要的就两个属性:contentRect
和target
,target
就不说了,就是当前监听的DOM节点。contentRect
则包含了这个DOM节点的参数,包括width、height、bottom、left、right、top、x和y
,这些应该足够使用了。
# 取消/暂时结束观察
ro.disconnct();
一般写在监听DOM节点被隐藏时(可以结合业务判断),主要目的是为了在隐藏/不再显示这段时间内暂时取消监听,节省开销。
那么在重新打开/进入模块时还需要重新监听:
if (ro) ro.observe();
# 终止观察
ro.unobserve();
模块销毁时彻底结束观察。
# 二、需要注意的
参考资料[1]中说了:
...在使用ResizeObserver API的时候,在每次触发元素的大小变化时,会在1s内触发回调蛮多次的。如果想进一步优化性能,可以加上throttle节流函数处理...
这里节流的话,在业务中实际使用会发现效果并不会流畅,就是会是一顿一顿的。
因为节流实际上把多个事件只取一个进行处理(并不是合并,也不会合并),比如监听返回了30
个事件,但却回调只执行了6
次。
虽然是节省了开销,防止连续触发回调事件,但是如果回调的方法是执行动画效果的话,就不会很连贯,这样的话可能还需要配合transition
这个CSS样式才行。