关于动态加载外部js的执行顺序
项目开发中提出了一个新的需求。
因为版本更新带来的html、js等的更新,但客户浏览器或多或少都会存在缓存问题。
这就需要根据版本信息去动态加载外部js。
但html中内置的一些javascript代码需要调用动态加载js中的参数和方法。
就导致了加载外部js必须阻塞内置的一些javascript代码。
利用document.createElement方法去创建scrip节点,但不能阻塞内置的javascript代码。
在W3help里找到了解决方法。
这里只截取解决方法的代码,还有很多测试加载顺序的代码就不贴出来了。可以参考http://www.w3help.org/zh-cn/causes/BX9013
function loadJS(url, success) {
var domScript = document.createElement('script');
domScript.src = url;
success = success || function(){};
domScript.onload = domScript.onreadystatechange = function() {
if (!this.readyState || 'loaded' === this.readyState || 'complete' === this.readyState) {
success();
this.onload = this.onreadystatechange = null;
this.parentNode.removeChild(this);
}
}
document.getElementsByTagName('head')[0].appendChild(domScript);
}
//执行加载外部 JS 文件,从a.js开始执行加载。
loadJS('a.js',function (){
loadJS('b.js',function (){
loadJS('c.js',function (){
alert('ok');
});
});
});
通过进一步了解onload和onreadystatechange,发现IE9/10同时支持script元素的onload和onreadystatechange事件。
所以上面的代码在IE9/10中会执行两次if中的代码。
替换方法就是写成
function loadJS(url, success) {
var domScript = document.createElement('script');
domScript.src = url;
success = success || function(){};
//domScript.onload = domScript.onreadystatechange = function() {
if(navigator.userAgent.indexOf("MSIE")>0){
domScript.onreadystatechange = function(){
if('loaded' === this.readyState || 'complete' === this.readyState){
success();
this.onload = this.onreadystatechange = null;
this.parentNode.removeChild(this);
}
}
}else{
domScript.onload = function(){
success();
this.onload = this.onreadystatechange = null;
this.parentNode.removeChild(this);
}
}
document.getElementsByTagName('head')[0].appendChild(domScript);
}
//执行加载外部 JS 文件,从a.js开始执行加载。
loadJS('a.js',function (){
loadJS('b.js',function (){
loadJS('c.js',function (){
alert('ok');
});
});
});