如何检测 div 的尺寸变化?

2,608 阅读2分钟

这是我参与更文挑战的第 10 天,活动详情查看:更文挑战


众所周知,window 有 resize 事件,可以通过 resize 事件做一些特殊的事情。但这个事件对普通的 HTML 元素,是不支持的。这给 echarts 图表自适应的场景带来了麻烦。

本文介绍几种简单的方式,来解决上述问题。

1. 使用 ResizeObserver

使用方法

  1. 确定想要被监听的元素 box
  2. 确定当被监听的元素尺寸发生变化时触发事件 onResize
  3. 使用 ResizeObserver 创建监听
const observer = new ResizeObserver(onResize).observe(box)
  1. 当页面或组件被销毁时断开监听(非必须)
observer.disconnect()

实例

1. resizeobserver

兼容性:现代浏览器均支持

caniuse.com/mdn-api_res…

image.png

2. 使用 relative + 100% + iframe/object

使用方法

  1. 将被监听的元素 box 设置为 relative,或者在元素外面增加一层元素 box,将外层元素设置为 relative,同时设置内层元素充满 box
  2. 创建一个 iframe 或者 object,令该元素的 id 为 helper。设置属性为 absolute,width 和 height 均为 100%,充满 box,并设置 visibility 为 hidden。这一步的操作
  3. 确定当被监听的元素尺寸发生变化时触发事件 onResize
  4. 监听 iframe 或 object 的 window 的 resize 事件,在事件回调中执行 onResize 方法

实例

2. iframe

兼容性:IE 也支持

在 IE11 下,使用 object 时会层叠在 box 内的元素上层,即使设置 z-index 的值为最低。这种情况下建议 transform 到可视区域外,或者仅使用 iframe。iframe 没有这个问题。

3. 使用定时器定期查询

使用方法

  1. 确定想要被监听的元素 box
  2. 确定当被监听的元素尺寸发生变化时触发事件 onResize
  3. 使用定时器 setInterval 循环查询 box 的 size,和上次储存的值比较,当不同时调用 onResize 方法

实例

3. raf

兼容性:IE 也支持

但使用 setInterval 进行轮询,每次获取尺寸时,都触发了一次重绘操作,这增加了浏览器的性能压力。

总结

  • 如果考虑对现代浏览器的支持,使用 ResizeObserver 最稳妥,就算是不支持的浏览器,可以使用 polyfill
  • 如果不想使用 polyfill,可以使用第二种方案 iframe。但第二种方案对 dom 结构有限制
  • 既然有了上面两种方式,定时器的方式就不需要了。相对前两种,对性能的影响较大