发生问题场景

系统页面使用tabs标签页,当有多个组件,有使用eCharts图表的页面时,其中的一个页面或其他页面使用了F11的页面全屏,关闭全屏后图表会收缩起来(注:固定eCharts的width、height 的参数值是无影响,按照固定参数大小展示),如使用百分比:

<div ref={myChartRef} style={{ width: '100%', height: '100%' }} />

会收缩,这时候window.addEventListener(‘resize’)(仅监听窗口)无法监听

优缺点

在监听窗口或元素尺寸变化时,window.addEventListener(‘resize’) 和 ResizeObserver 是两种常见方法,各有优缺点。以下是详细对比:

1. window.addEventListener(‘resize’)

优点

  • 广泛兼容性
  • 所有浏览器均支持,包括旧版本(如 IE9+)。
  • 简单直接
  • 监听整个窗口的尺寸变化,代码简洁,适合全局布局调整。
  • 性能优化空间
  • 可通过防抖(debounce)或节流(throttle)减少回调触发频率。

缺点

  • 仅监听窗口
  • 无法直接监听特定元素的尺寸变化(如 div、iframe 等)。
  • 触发频率高
  • 浏览器窗口调整时可能连续触发多次回调,需手动优化(如防抖)。
  • 无法获取变化前后的尺寸
  • 需自行存储上一次的尺寸值进行比较。
  • 移动端问题
  • 虚拟键盘弹出/收起可能触发 resize,但实际窗口尺寸未变,需额外处理。
    示例代码
javascript
window.addEventListener('resize', debounce(() => {
  console.log('窗口尺寸变化:', window.innerWidth, window.innerHeight);
}, 200));
 
function debounce(fn, delay) {
  let timer;
  return () => {
    clearTimeout(timer);
    timer = setTimeout(fn, delay);
  };
}

2. ResizeObserver

优点

  • 监听任意元素
  • 可精确监听特定 DOM 元素的尺寸变化(包括 width、height、padding、border 等)。
  • 高效触发
  • 浏览器内部优化,仅在尺寸实际变化时触发回调,避免冗余计算。
  • 提供详细信息
  • 回调中直接返回元素的 contentRect(内容尺寸)和 borderBoxSize(边框盒尺寸)。
  • 现代标准
  • 专为动态尺寸监听设计,是W3C 推荐方案。

缺点

  • 兼容性限制
  • 不支持 IE 和旧版 Edge(需 Polyfill 或降级处理)。
  • 初始尺寸不触发
  • 仅在尺寸变化时触发,若需初始尺寸需额外调用一次。
  • 循环观察风险
  • 若回调中修改元素尺寸,可能导致无限循环(需谨慎处理)。
    示例代码

const element = document.getElementById('target');
const observer = new ResizeObserver((entries) => {
  for (let entry of entries) {
    console.log('元素尺寸变化:', entry.contentRect);
  }
});
 
observer.observe(element); // 开始观察
// observer.unobserve(element); // 停止观察

对比总结

在这里插入图片描述

// 优先使用 ResizeObserver,不支持时回退到 resize + 防抖
if ('ResizeObserver' in window) {
  const observer = new ResizeObserver(/* ... */);
  observer.observe(element);
} else {
  // 使用 resize 事件 + 防抖(需通过其他方式获取元素尺寸)
}

根据项目需求和浏览器支持情况灵活选择即可。

更多推荐