面试题:如何对一个div做监听,监听他的长宽的大小变化

监听 DIV 元素尺寸变化的几种方法

在 Web 开发中,监听 DOM 元素尺寸变化是一个常见需求。以下是几种实现监听 DIV 长宽变化的方法:

1. 使用 ResizeObserver API(现代推荐方式)

ResizeObserver 是现代浏览器提供的专门用于监听元素尺寸变化的 API。

复制代码
const divElement = document.getElementById('myDiv');

const observer = new ResizeObserver(entries => {
  for (let entry of entries) {
    const { width, height } = entry.contentRect;
    console.log(`宽度: ${width}px, 高度: ${height}px`);
    
    // 或者获取更精确的尺寸
    console.log(`精确宽度: ${entry.contentBoxSize[0].inlineSize}px`);
    console.log(`精确高度: ${entry.contentBoxSize[0].blockSize}px`);
  }
});

// 开始观察
observer.observe(divElement);

// 停止观察(需要时)
// observer.unobserve(divElement);

React 组件中的使用示例

复制代码
import { useEffect, useRef } from 'react';

function ResizableDiv() {
  const divRef = useRef(null);
  
  useEffect(() => {
    const observer = new ResizeObserver(entries => {
      const { width, height } = entries[0].contentRect;
      console.log('尺寸变化:', width, height);
    });
    
    if (divRef.current) {
      observer.observe(divRef.current);
    }
    
    return () => {
      if (divRef.current) {
        observer.unobserve(divRef.current);
      }
    };
  }, []);

  return <div ref={divRef} style={{ width: '50%', resize: 'both', overflow: 'auto' }}>
    可调整大小的DIV
  </div>;
}

2. 使用 window.resize 事件(有限场景)

这种方法只适用于窗口大小变化导致元素尺寸变化的情况:

复制代码
const divElement = document.getElementById('myDiv');

function checkSize() {
  const width = divElement.offsetWidth;
  const height = divElement.offsetHeight;
  console.log(`当前尺寸: ${width}x${height}`);
}

// 初始检查
checkSize();

// 监听窗口大小变化
window.addEventListener('resize', checkSize);

3. 轮询检查(不推荐,仅作备选)

复制代码
const divElement = document.getElementById('myDiv');
let lastWidth = divElement.offsetWidth;
let lastHeight = divElement.offsetHeight;

setInterval(() => {
  const currentWidth = divElement.offsetWidth;
  const currentHeight = divElement.offsetHeight;
  
  if (currentWidth !== lastWidth || currentHeight !== lastHeight) {
    console.log(`尺寸变化: ${currentWidth}x${currentHeight}`);
    lastWidth = currentWidth;
    lastHeight = currentHeight;
  }
}, 100); // 每100毫秒检查一次

4. 使用 CSS transition 和 transitionend 事件

如果尺寸变化是通过 CSS 动画/过渡实现的:

复制代码
const divElement = document.getElementById('myDiv');

divElement.addEventListener('transitionend', (event) => {
  if (event.propertyName === 'width' || event.propertyName === 'height') {
    console.log('尺寸变化完成:', 
      divElement.offsetWidth, 
      divElement.offsetHeight
    );
  }
});

5. 使用第三方库(兼容旧浏览器)

如果需要支持旧版浏览器,可以使用这些库:

  • resize-observer-polyfill

  • element-resize-detector

    // 使用 resize-observer-polyfill
    import ResizeObserver from 'resize-observer-polyfill';

    const ro = new ResizeObserver(entries => {
    for (let entry of entries) {
    console.log('新尺寸:', entry.contentRect.width, entry.contentRect.height);
    }
    });
    ro.observe(document.getElementById('myDiv'));

最佳实践建议

  1. 优先使用 ResizeObserver - 这是最现代、最高效的方式

  2. 注意性能 - 在回调函数中避免昂贵操作

  3. 及时清理 - 组件卸载时取消观察

  4. 防抖处理 - 如果尺寸变化频繁,考虑添加防抖

完整 React Hook 实现

复制代码
import { useEffect, useState, useRef } from 'react';

function useElementSize() {
  const ref = useRef(null);
  const [size, setSize] = useState({
    width: 0,
    height: 0
  });

  useEffect(() => {
    if (!ref.current) return;

    const observer = new ResizeObserver((entries) => {
      const { width, height } = entries[0].contentRect;
      setSize({ width, height });
    });

    observer.observe(ref.current);
    
    return () => {
      observer.disconnect();
    };
  }, []);

  return [ref, size];
}

// 使用示例
function Component() {
  const [divRef, size] = useElementSize();
  
  return (
    <div ref={divRef}>
      当前尺寸: {size.width} x {size.height}
    </div>
  );
}

以上方法可以根据你的具体需求和技术环境选择最适合的方案。

相关推荐
IT_陈寒10 分钟前
SpringBoot实战避坑指南:我在微服务项目中总结的12条高效开发经验
前端·人工智能·后端
华洛13 分钟前
解读麦肯锡报告:Agent落地的六大经验教训
前端·javascript·产品经理
艾小码26 分钟前
还在重复造轮子?掌握这7个原则,让你的Vue组件复用性飙升!
前端·javascript·vue.js
探索宇宙真理.27 分钟前
React Native Community CLI命令执行 | CVE-2025-11953 复现&研究
javascript·经验分享·react native·react.js·安全漏洞
. . . . .1 小时前
React底层原理
javascript·react.js
2401_831501731 小时前
Web网页之前端三剑客汇总篇(基础版)
前端
木易 士心2 小时前
Vue 3 Props 响应式深度解析:从原理到最佳实践
前端·javascript·vue.js
海鸥两三5 小时前
uniapp 小程序引入 uview plus 框架,获得精美的UI框架
前端·vue.js·ui·小程序·uni-app
lightgis6 小时前
16openlayers加载COG(云优化Geotiff)
前端·javascript·html·html5
小飞大王6666 小时前
TypeScript核心类型系统完全指南
前端·javascript·typescript