react echarts图表监听窗口变化window.addEventListener(‘resize’)与ResizeObserver()
发生问题场景
系统页面使用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 事件 + 防抖(需通过其他方式获取元素尺寸)
}
根据项目需求和浏览器支持情况灵活选择即可。