【JS】ResizeObserver(用于监听元素尺寸变化的接口)

发布于:2025-07-24 ⋅ 阅读:(19) ⋅ 点赞:(0)

文章目录

基础用法

  1. 创建 ResizeObserver 实例:通过构造函数创建一个观察器,并传入一个回调函数。该回调函数会在元素尺寸变化时执行。
  2. 指定要观察的元素:使用 observe() 方法开始观察指定的元素。
  3. 停止观察:可以使用 unobserve() 方法停止观察特定元素,或使用 disconnect() 方法停止观察所有元素。

语法

const resizeObserver = new ResizeObserver(callback);

其中,callback 是一个函数,它接收两个参数:

  • entries:一个 ResizeObserverEntry 对象的数组,每个对象代表一个被观察元素的尺寸变化信息。
  • observer:对 ResizeObserver 实例本身的引用。

ResizeObserverEntry 对象

每个 ResizeObserverEntry 对象包含以下属性:

属性 描述
target 被观察的元素。
contentRect 一个 DOMRectReadOnly 对象,包含元素内容区域的尺寸和位置信息(width, height, top, right, bottom, left, x, y)。
borderBoxSize 一个数组(为了支持多片段布局,如多列),包含一个对象,该对象有 blockSize(垂直方向尺寸,相当于高度)和 inlineSize(水平方向尺寸,相当于宽度)属性。注意:在部分浏览器中可能不是数组。
contentBoxSize 同上,但描述内容区域。
devicePixelContentBoxSize 同上,但尺寸以设备像素为单位。

注意:borderBoxSizecontentBoxSizedevicePixelContentBoxSize 是较新的属性,可能在一些浏览器中不支持。

示例代码

// 创建观察器实例
const resizeObserver = new ResizeObserver((entries) => {
  for (const entry of entries) {
    // 使用 contentRect
    console.log('元素高度:', entry.contentRect.height);
    console.log('元素宽度:', entry.contentRect.width);
    // 或者使用 borderBoxSize(注意:可能是一个数组)
    if (entry.borderBoxSize) {
      // 标准方式:borderBoxSize 是一个数组(处理多片段情况,通常只有一个元素)
      const borderBoxSize = Array.isArray(entry.borderBoxSize) ? entry.borderBoxSize[0] : entry.borderBoxSize;
      console.log('borderBox 高度:', borderBoxSize.blockSize);
      console.log('borderBox 宽度:', borderBoxSize.inlineSize);
    }
    // 同样,contentBoxSize 也是数组
    if (entry.contentBoxSize) {
      const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;
      console.log('contentBox 高度:', contentBoxSize.blockSize);
      console.log('contentBox 宽度:', contentBoxSize.inlineSize);
    }
  }
});
// 选择要观察的元素
const element = document.getElementById('myElement');
// 开始观察元素
resizeObserver.observe(element);
// 如果需要停止观察单个元素
// resizeObserver.unobserve(element);
// 停止观察所有元素
// resizeObserver.disconnect();

框架示例

React 示例(使用钩子)

import { useEffect, useRef } from 'react';
function ResizeObserverComponent() {
  const elementRef = useRef(null);
  useEffect(() => {
    const element = elementRef.current;
    if (!element) return;
    const resizeObserver = new ResizeObserver((entries) => {
      for (const entry of entries) {
        console.log('尺寸变化:', entry.contentRect);
      }
    });
    resizeObserver.observe(element);
    // 清理函数
    return () => {
      resizeObserver.disconnect();
    };
  }, []);
  return <div ref={elementRef}>监听我的尺寸变化</div>;
}

Vue 示例(组合式 API)

<template>
  <div ref="targetElement">监听我的尺寸变化</div>
</template>
<script>
import { ref, onMounted, onBeforeUnmount } from 'vue';
export default {
  setup() {
    const targetElement = ref(null);
    onMounted(() => {
      const resizeObserver = new ResizeObserver((entries) => {
        for (const entry of entries) {
          console.log('尺寸变化:', entry.contentRect);
        }
      });
      resizeObserver.observe(targetElement.value);
      // 组件卸载前停止监听
      onBeforeUnmount(() => {
        resizeObserver.disconnect();
      });
    });
    return { targetElement };
  }
};
</script>

网站公告

今日签到

点亮在社区的每一天
去签到