JS怎样监听元素尺寸变化?ResizeObserver使用指南

来源:PHP编程网作者:美园和花头衔:网络博主
导读:本期聚焦于小伙伴创作的《JS怎样监听元素尺寸变化?ResizeObserver使用指南》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JS怎样监听元素尺寸变化?ResizeObserver使用指南》有用,将其分享出去将是对创作者最好的鼓励。

在前端开发中,监听元素尺寸变化是常见的需求,比如侧边栏折叠后内容区域自适应、图表跟随容器大小调整显示效果等。过去开发者通常会使用window的resize事件配合getBoundingClientRect方法轮询检测,或者用MutationObserver监听元素属性变化间接判断尺寸,但这些方式要么覆盖范围有限,要么性能开销较高。ResizeObserver是浏览器原生提供的专门用于监听元素尺寸变化的API,能够直接监听指定元素的宽高变化,使用起来更加高效便捷。

JS怎样监听元素尺寸变化?ResizeObserver使用指南

ResizeObserver基本用法

ResizeObserver的使用流程和MutationObserver类似,主要分为三步:创建观察者实例、定义回调函数、指定要观察的元素。

1. 创建ResizeObserver实例

通过new ResizeObserver()创建实例,构造函数接收一个回调函数,当被观察的元素尺寸发生变化时,这个回调会被触发。

// 创建ResizeObserver实例
const resizeObserver = new ResizeObserver((entries) => {
  // entries是所有发生尺寸变化的元素的信息数组
  entries.forEach(entry => {
    console.log('元素尺寸变化了', entry);
  });
});

2. 监听指定元素

使用observe方法指定要监听的元素,可以多次调用该方法监听多个不同的元素。

// 获取要监听的元素
const targetElement = document.querySelector('.content-box');
// 开始监听该元素
resizeObserver.observe(targetElement);

3. 停止监听

当不再需要监听某个元素时,可以调用unobserve方法停止对该元素的监听;如果要停止所有监听,可以调用disconnect方法。

// 停止监听单个元素
resizeObserver.unobserve(targetElement);
// 停止所有监听
resizeObserver.disconnect();

回调函数参数详解

ResizeObserver的回调函数接收一个entries数组,数组中的每个元素都是ResizeObserverEntry对象,包含了对应元素的变化信息,常用的属性如下:

属性名说明
target发生尺寸变化的DOM元素
contentRect元素的内容矩形信息,包含x、y、width、height、top、right、bottom、left等属性
borderBoxSize元素的边框盒尺寸数组,包含blockSize(块方向尺寸,对应高度)和inlineSize(行内方向尺寸,对应宽度)
contentBoxSize元素的内容盒尺寸数组,同样包含blockSize和inlineSize

下面是一个使用回调参数获取元素最新尺寸的例子:

const resizeObserver = new ResizeObserver((entries) => {
  entries.forEach(entry => {
    const { width, height } = entry.contentRect;
    console.log(`元素当前尺寸:宽度${width}px,高度${height}px`);
    // 可以在这里处理尺寸变化后的逻辑,比如调整图表大小
  });
});

const chartContainer = document.querySelector('#chart-container');
resizeObserver.observe(chartContainer);

常见使用场景

1. 响应式内容自适应

当侧边栏折叠或展开时,右侧内容区域的宽度会发生变化,使用ResizeObserver可以监听内容区域的尺寸变化,动态调整内部组件的布局。

const contentArea = document.querySelector('.main-content');
const resizeObserver = new ResizeObserver((entries) => {
  const { width } = entries[0].contentRect;
  // 根据宽度调整内部卡片的列数
  const cardContainer = contentArea.querySelector('.card-container');
  if (width < 768) {
    cardContainer.style.gridTemplateColumns = '1fr';
  } else if (width < 1200) {
    cardContainer.style.gridTemplateColumns = 'repeat(2, 1fr)';
  } else {
    cardContainer.style.gridTemplateColumns = 'repeat(3, 1fr)';
  }
});
resizeObserver.observe(contentArea);

2. 图表自适应容器

很多图表库需要明确容器的尺寸才能正确渲染,当容器尺寸变化时,需要重新渲染图表。使用ResizeObserver可以在容器尺寸变化时触发图表的重新绘制。

// 假设已经初始化了一个echarts实例
const chartDom = document.querySelector('#my-chart');
const myChart = echarts.init(chartDom);

const resizeObserver = new ResizeObserver(() => {
  // 容器尺寸变化时重新调整图表大小
  myChart.resize();
});
resizeObserver.observe(chartDom);

注意事项

  • ResizeObserver的回调是异步执行的,并且会在浏览器下一帧绘制前触发,不会阻塞主线程。
  • 如果在回调中修改了被观察元素的尺寸,可能会导致无限循环的回调触发,需要做好逻辑判断避免这种情况。
  • 旧版本浏览器可能不支持ResizeObserver,使用前可以通过'ResizeObserver' in window判断兼容性,不支持的情况下可以降级使用传统的resize事件或者定时器轮询方案。
  • 观察SVG元素时,ResizeObserver同样可以生效,获取到的contentRect是SVG元素在页面中的实际渲染尺寸。

兼容性处理示例

如果需要兼容不支持ResizeObserver的浏览器,可以添加降级逻辑:

function createResizeListener(element, callback) {
  if ('ResizeObserver' in window) {
    const observer = new ResizeObserver((entries) => {
      callback(entries[0].contentRect);
    });
    observer.observe(element);
    return {
      destroy: () => observer.disconnect()
    };
  } else {
    // 降级方案:监听window的resize事件,结合getBoundingClientRect检测
    let lastRect = element.getBoundingClientRect();
    const handleResize = () => {
      const currentRect = element.getBoundingClientRect();
      if (currentRect.width !== lastRect.width || currentRect.height !== lastRect.height) {
        callback(currentRect);
        lastRect = currentRect;
      }
    };
    window.addEventListener('resize', handleResize);
    // 可以额外添加定时器检测,应对非window resize导致的尺寸变化
    const timer = setInterval(handleResize, 500);
    return {
      destroy: () => {
        window.removeEventListener('resize', handleResize);
        clearInterval(timer);
      }
    };
  }
}

// 使用方式
const target = document.querySelector('.box');
const listener = createResizeListener(target, (rect) => {
  console.log('尺寸变化', rect.width, rect.height);
});
// 不需要监听时销毁
// listener.destroy();

ResizeObserver元素尺寸监听JavaScript前端性能优化修改时间:2026-06-09 18:39:22

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。