ResizeObserver是一个强大的 JavaScript API,它使开发人员能够轻松地监听和响应 DOM 元素的大小变化。本文将深入了解ResizeObserver的用法和潜力。

注意❗

注意:ResizeObserver生效的前提是DOM元素要宽度或者高度变化才行,一般DOM元素宽度会设置成 100%,或者高度亦如此。这样改变视口宽高后,ResizeObserver 方法才能正确监听DOM元素变化。

ResizeObserver有什么优势?

在传统的前端开发中,监听并响应元素的大小变化需要依靠窗口的 ‘resize’ 事件,然后手动计算元素的大小,这既低效又麻烦。现在,ResizeObserver API 使这一切变得更简单、更直接,它允许你直接观察一个元素的尺寸是否发生了变化

基本用法

要使用 ResizeObserver,你需要首先创建一个新的 ResizeObserver 对象,并传递一个回调函数,该回调函数在所观察的元素尺寸发生变化时被触发。

 let observer;
 if (window.ResizeObserver){
   observer = new ResizeObserver(entries => {
      for (let entry of entries) {
            console.log(entry.target);
            console.log(`Element size: 
            ${entry.contentRect.width}px x 
            ${entry.contentRect.height}px`
        );
      };
    });
 } else {
     console.log("Resize observer not supported!");
 }

这个回调函数接收一个entries参数,每个entry对象都代表了一个被观察元素的一次尺寸变化,包含了该元素的相关信息,如目标元素(entry.target)、新的尺寸(entry.contentRect)等。

然后,使用observe()函数来指定需要观察的元素:

 
let element = document.querySelector('#myElement');
observer.observe(element);

以上代码表示开始观察 id 为 “myElement” 的元素。一旦该元素的大小发生变化,我们就可以在 console 中看到输出的新尺寸。

停止监听

如果你不再需要观察元素,可以调用unobserve()来停止观察:

observer.unobserve(element);

如果你想停止观察所有元素,可以调用 disconnect() 方法:

observer.disconnect();

ResizeObserver 在vue3项目中的应用

作为前端开发者,想必大家都用过ResizeObserver 来监听DOM尺寸变化,然后根据变化做一些业务或者功能。这里和大家分享实现监听div元素变化来修改canvas尺寸的功能。同一个功能,有两种写法。

第一种:采用 vueuse 库

vueuse是vue3的组合式API第三方库,里面包含了很多实用有趣的组合式API,为开发者节约了很多学习成本,可谓是开箱即用的效率。它有一个专门监听DOM元素变化的useResizeObserver API,只需要传递参数即可实时监听DOM元素和动态获取变化尺寸值。

1、导入方法:

import { useResizeObserver } from '@vueuse/core'

2、监听目标:

<div 
  ref="fabricDesginRef" 
  id="workspace" 
  class="fabric-desgin__content">
    <canvas class="canvas" id="canvas"></canvas>
</div>

3、实现监听:

这里需要在setup模块内,写一个ref绑定DOM,同时传递给useResizeObserver 方法,当然,这里也要打印监听结果,方便观察监听是否生效。

const fabricDesginRef = ref(null);
// 容器发生改变后,重新计算画布大小
useResizeObserver(fabricDesginRef, (entries) => {
    const entry = entries[0]
    const { width, height } = entry.contentRect
    // 这里可以更新canvas的width和height的值
    console.log(`width: ${width}, height: ${height}`, 7777);
    // 做一些其他业务处理逻辑...
})

缩放浏览器视口大小,div尺寸发生变化,那么监听即可生效。

第二种:在js中采用原生写法监听DOM元素变化

这种需求一般是将页面的DOM元素ID传递到js,通过document来获取真实的DOM元素对象,并将对象传递给ResizeObserver进行监听操作,而外部无需关系内部逻辑,可以通过callback回调函数接收DOM元素变化值。

export const initResizeObserve = (ID, callback) 
    =>{
    let params = {
        width: 0,
        height: 0
    }
    if (!window.ResizeObserver) {
        console.warn('Resize observer not supported! 
        will lose the automatic change function!')
        return
    }
    const resizeObsever = new ResizeObserver(entries => {
        for (let entry of entries) {
              console.log(entry.target);
              console.log(`Element size: 
              ${entry.contentRect.width}px x 
              ${entry.contentRect.height}px`);
              params = { 
                width: entry.contentRect.width,
                height: entry.contentRect.height
              }
              callback(params)
        };
    });
    // 指定需要监听的DOM元素
    resizeObsever.observe(this.workspaceEl)
 }

关于ResizeObserver 

ResizeObserver 提供了强大而又灵活的监听和响应元素尺寸变化的能力,使得我们可以轻松构建响应式的用户界面。不过,它也有一些局限性,例如不能监听元素的位置变化。在使用时,需要根据具体需求来慎重选择是否使用。希望这篇文章能帮助你理解并开始使用 ResizeObserver。