面试题:如何对一个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>
  );
}

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

相关推荐
Cache技术分享2 分钟前
360. Java IO API - 访问文件系统
前端·后端
计算机学姐11 分钟前
基于SpringBoot的校园二手交易系统
java·vue.js·spring boot·后端·spring·tomcat·intellij-idea
小璐资源网12 分钟前
CSS进阶指南:深入解析选择器优先级与继承机制
前端·css
工边页字17 分钟前
为什么 RAG系统里,Embedding成本往往远低于 LLM成本,但很多公司仍然疯狂优化 Embedding?
前端·人工智能·后端
墨渊君18 分钟前
OpenClaw 上手实践: 使用 Docker 从构建到可用全流程指南
前端·agent
冰暮流星20 分钟前
javascript之回调函数
开发语言·前端·javascript
米丘24 分钟前
Rollup 打包工具
前端
We་ct25 分钟前
LeetCode 74. 搜索二维矩阵:两种高效解题思路
前端·算法·leetcode·矩阵·typescript·二分查找
moneyinto25 分钟前
Three.js 必背核心方法
前端
wuhen_n27 分钟前
Vue3 组件中的图片懒加载与渐进式加载
前端·javascript·vue.js