手头上有个 vue 项目,一些不同的 js 包 被加载到了同一个页面,导致一个页面里可能有一个以上的 window.onload ,这样做的后果就是前面的回调函数会被后面的覆盖掉。
大多数情况下的解决方案有:
- 重写 window.onload 方法;
- 使用 window.addEventListener ;
- 使用setTimeout
但对于引入的js来说无法修改代码,以上方式都不适用,于是利用 Object.defineProperty 劫持 window.onload 的赋值行为,把对应的回调函数放到一个队列中进行处理。
const eventQueue = []
Object.defineProperty(window, 'onload', {
set(fn) {
fn instanceof Function && eventQueue.push(window.onload);
console.log('eventQueue添加了回调', fn);
}
})
// 需在页面加载完成后执行
setTimeout(() => {
eventQueue.forEach(fn => {
// 执行回调
try {
fn.call(window)
} catch (error) {
console.log(error);
}
})
}, 0);