export const GlobalResizeObserver = (function () {
const ATTR_NAME = 'global-resizeobserver-key'
const attrValueToCallback = {}
function antiShake(fn, delay, immediate = false) {
let timer = null
//不能用箭头函数
return function () {
//在时间内重复调用的时候需要清空之前的定时任务
if (timer) {
clearTimeout(timer)
}
//适用于首次需要立刻执行的
if (immediate && !timer) {
fn.apply(this, arguments)
}
timer = setTimeout(() => {
fn.apply(this, arguments)
}, delay)
}
}
// const fn = antiShake((callback, entry) => {
// callback(entry)
// }, 300)
const o = new ResizeObserver((entries) => {
for (const entry of entries) {
const resizedElement = entry.target
const attrValue = resizedElement.getAttribute(ATTR_NAME)
if (attrValue) {
const callback = attrValueToCallback[attrValue]
if (typeof callback === 'function') {
callback()
// fn(callback, entry)
}
}
}
})
return Object.freeze({
/**
* @param { Element } element
* @param { (ResizeObserverEntry) => {} } callback
*/
observe(chart) {
if (!(chart._dom instanceof Element)) {
console.error('GlobalResizeObserver, cannot observe non-Element.')
return
}
let attrValue = chart._dom.getAttribute(ATTR_NAME)
if (!attrValue) {
attrValue = String(Math.random())
chart._dom.setAttribute(ATTR_NAME, attrValue)
}
// 为每个元素创建独立的防抖函数
const debouncedResize = antiShake(() => {
chart.resize()
}, 300)
attrValueToCallback[attrValue] = debouncedResize
// attrValueToCallback[attrValue] = chart.resize
o.observe(chart._dom)
},
/**
* @param { Element } element
*/
unobserve(chart) {
if (!(chart._dom instanceof Element)) {
console.error('GlobalResizeObserver cannot unobserve non-Element.')
return
}
const attrValue = chart._dom.getAttribute(ATTR_NAME)
if (!attrValue) {
console.error(
'GlobalResizeObserver cannot unobserve element w/o ATTR_NAME.',
)
return
}
delete attrValueToCallback[attrValue]
o.unobserve(chart._dom)
chart.dispose()
},
})
})()
使用方式
先去mainjs去注册
import {GlobalResizeObserver} from '@/utils/echartsResize.js'
Vue.prototype.GlobalResizeObserver = GlobalResizeObserver
在vue2里面使用
destroyed() {
this.GlobalResizeObserver.unobserve(this.radarChart)
this.GlobalResizeObserver.unobserve(this.lineChart)
},
methods: {
initEcharts() {
this.radarChart = echarts.init(document.querySelector('#radar'))
this.lineChart = echarts.init(document.querySelector('#line'))
this.GlobalResizeObserver.observe(this.radarChart)
this.GlobalResizeObserver.observe(this.lineChart)
},
}
有个小的地方需要注意 像这种布局
尽量使用width百分比来渲染 尽量不用flex-grow 缩放虽然没问题 但调整浏览器的大小就会有不触发的情况