最近遇到一个需要,就是谷歌地图的地址需要购买谷歌地图后收到填入,这样导致的问题是,谷歌地图会可能会被频繁的替换,出现一些不可预见的错误。
问题
当我们引用谷歌服务地址如:https://maps.googleapis.com/maps/api/js?key=unique_code&language=zh-CN 在页面加载该js时,会自动加载出多个与google地图相关的js代码,最终将全局对象google.Maps挂载到window对象上。这样当我们切换地址,会出现如下问题:
1)只是将script标签src的属性替换,就会造成依赖的加载依然是旧的,而且新的js也会加载大量的js文件,造成冲突;再者之前加载到内存里面的多个对象并没有被回收,造成对象重复冲突等不可预期问题。
2)动态替换js,因为script一般是异步加载的,而当前业务建立在地图上,会出现地图js没有加载完,而先执行了基于google API的代码,造成错误
解决办法
思路:将所有与google项目的node删除掉,检测js是否加载完成,加载完成执行业务方法的回调
/**
* 动态添加外部js,js加载完成,执行回调
* @param url script的src的地址
* @param callback 回调函数执行
* @param srckey 要替换的src包含的字段 这里加载的是谷歌地图maps.googleapis.com'
*/
export function changeScript({url,srckey,callback}){
// 删除之前的script
const scripts = document.querySelectorAll('script');
for(const script of scripts){
if(script.src.includes(srckey)){
script.parentNode.removeChild(script);
}
}
document.execCommand('Refresh');
// 重新创建script
const script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.defer = true;
if (script.readyState) { // IE
script.onreadystatechange = function () {
if (script.readyState === "loaded" || script.readyState === "complete") {
script.onreadystatechange = null;
callback();
}
};
} else { // Others
script.onload = function () {
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}