关于动态加载外部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');
});
});
});
posted @ 2012-03-19 16:32  connie1120  阅读(2916)  评论(0编辑  收藏  举报