ie下动态加态js文件的方法


Posted in Javascript onSeptember 13, 2011

这里只讨论支持并行下载的浏览情况,大致分为两种,一种是按加向DOM树中加的顺序执行,另一种按下载完成的先后顺序执行;这样如果js文件间有依赖关系的话,且是按下载顺序执行,且在没有缓存的情况下就会报错(通常的情况下第一次执行会报错,http返回状态200,如果缓存未禁用,http状态是304,就不会报错了)
而ie就是按http下载完成的先后顺序执行js代码的,首先看下面的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" lang="zh-CN"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>Model</title> 
<meta http-equiv="Content-language" content="zh-CN" /> 
</head> 
<body> 
<div id="page"> 
</div><!-- Page end! --> 
<script type="text/javascript"> 
//<![CDATA[ 
var js = document.createElement('script'); 
js.type = 'text/javascript'; 
js.src = 'alert.js'; 
if(js.readyState){ 
js.onreadystatechange = function(){ 
if (js.readyState == "loaded" || js.readyState == "complete"){ 
alert(js.readyState); 
document.getElementsByTagName('head')[0].appendChild(js); 
} 
}; 
}else{ 
document.getElementsByTagName('head')[0].appendChild(js); 
js.onload = function(){ 
alert('loaded not in ie!'); 
}; 
} 
//]]> 
</script> 
</body> 
</html>

其中动态加载的alert.js文件中内容为:alert('in alert.js');
经过测试(ie8),可以发现弹出的内容先后为:loaded、in alert.js、complete
查资料可得ie下向DOM中添加script时有onreadystatechange事件(其它浏览器有onload事件),而事件中js.readyState的状态变化为:loading(下载中)、loaded(下载完成)、complete(代码执行完成)
从代码中可以看出我是在事件中才向DOM中添加创建的scrip结点的……
因此可以得出ie在创建scrip结点并给src赋值时就开始有http下载了,这与其它浏览器完全不同(其它浏览器是要把script结点加到DOM中才会有http下载的),而把scrip结点向DOM树中添加后才开始执行代码。
有了这些结论我们就可以解决ie下并行下载顺序执行的问题了;有两种方案:一种是边下载边顺序执行,另一种是全下载完再顺序执行。
两种各有好处,这里给出后一种情况的代码(loader.js):
/* 
* Author: JaiHo 
*/ 
(function(window){ 
var DOMLoader = (function(){ 
var DOMLoader = function(){ 
return new DOMLoader.prototype.init(); 
}; 
DOMLoader.prototype = { 
jsList:[], js_all:0, loaded_js:0, 
head:document.getElementsByTagName('head')[0], 
init:function(){ }, 
create_node:function(src){ 
var js = document.createElement('script'); 
js.type = 'text/javascript'; 
this.bindWait(js); 
this.jsList[this.jsList.length] = js; 
js.src = src; 
}, 
loadJS:function(list){ 
len = list.length; 
for(var i=0; i<len; i++){ 
if( i==len-1 ) 
this.js_all = len; 
this.create_node(list[i]); 
} 
return this; 
}, 
bindWait:function(js){ 
if(arguments.callee.caller!==this.create_node) return; 
var that = this; 
if(js.readyState){ 
js.onreadystatechange = function(){ 
if( js.readyState == 'loaded' ){ 
that.loaded_js++; 
if( that.js_all == that.loaded_js ){ 
that.head.appendChild( that.jsList.shift() ); 
} 
} 
if ( js.readyState == "complete" ){ 
js.onreadystatechange = null; 
if( that.jsList.length ){ 
that.head.appendChild( that.jsList.shift() ); 
} 
} 
}; 
}else{ 
js.onload = function(){ 
alert('not in ie!'); 
}; 
} 
return this; 
} 
}; 
DOMLoader.prototype.init.prototype = DOMLoader.prototype; 
return window.DOMLoader = DOMLoader; 
})(); 
})(window);

测试例子如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" lang="zh-CN"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
<title>Loader</title> 
<meta http-equiv="Content-language" content="zh-CN" /> 
<style type="text/css" media="all"> 
</style> 
</head> 
<body> 
<div> 
</div> 
<script type="text/javascript" src="loader.js"></script> 
<script type="text/javascript"> 
//<![CDATA[ 
window.onload = function(){ 
var loader = DOMLoader(); 
loader.loadJS([ 'json.js', 'jquery-1.5.min.js', 'test.js' ]); 
}; 
//]]> 
</script> 
</body> 
</html>

ie下动态加态js文件的方法

      可以看出加载的3个js文件是并行下载的。
      对于其它浏览器有动态加载js文件的并行下载和顺序执行问题的情况,目前还没有相对完美的解决方案(如果有了请指教一下。。),单从这个方面,个人觉得ie的这个onreadystatechange事件方案相对好些。

Javascript 相关文章推荐
jsPDF导出pdf示例
May 02 Javascript
深入理解JavaScript系列(35):设计模式之迭代器模式详解
Mar 03 Javascript
jQuery焦点控制图层展示延迟隐藏的方法
Mar 09 Javascript
BootStrap的JS插件之轮播效果案例详解
May 16 Javascript
jQuery中animate的几种用法与注意事项
Dec 12 Javascript
新闻上下滚动jquery 超简洁(必看篇)
Jan 21 Javascript
jquery.form.js异步提交表单详解
Apr 25 jQuery
Vue实现virtual-dom的原理简析
Jul 10 Javascript
浅谈angularJS的$watch失效问题的解决方案
Aug 11 Javascript
three.js中文文档学习之通过模块导入
Nov 20 Javascript
Angular实现双向折叠列表组件的示例代码
Nov 21 Javascript
配置node服务器并且链接微信公众号接口配置步骤详解
Jun 21 Javascript
使用Json比用string返回数据更友好,也更面向对象一些
Sep 13 #Javascript
TextArea不支持maxlength的解决办法(jquery)
Sep 13 #Javascript
JQuery与JSon实现的无刷新分页代码
Sep 13 #Javascript
js Event对象的5种坐标
Sep 12 #Javascript
由JavaScript中call()方法引发的对面向对象继承机制call的思考
Sep 12 #Javascript
腾讯UED 漂亮的提示信息效果代码
Sep 12 #Javascript
jQuery的.live()和.die() 使用介绍
Sep 10 #Javascript
You might like
php源码加密 仿微盾PHP加密专家(PHPCodeLock)
2010/05/06 PHP
php echo 输出字符串函数详解
2010/05/13 PHP
javascript 小型动画组件与实现代码
2010/06/02 PHP
Notice: Undefined index: page in E:\PHP\test.php on line 14
2010/11/02 PHP
解析Linux下Varnish缓存的配置优化
2013/06/20 PHP
php除数取整示例
2014/04/24 PHP
php中的异常和错误浅析
2017/05/03 PHP
PHP将英文数字转换为阿拉伯数字实例讲解
2019/01/28 PHP
基于jQuery的遍历同id元素 并响应事件的代码
2012/06/14 Javascript
利用javascript数组长度循环数组内所有元素
2013/12/27 Javascript
JavaScript获取table中某一列的值的方法
2014/05/06 Javascript
javascript搜索框效果实现方法
2015/05/14 Javascript
js文字横向滚动特效
2015/11/11 Javascript
mvvm双向绑定机制的原理和实现代码(推荐)
2016/06/07 Javascript
如何获取元素的最终background-color
2017/02/06 Javascript
jquery编写日期选择器
2017/03/16 Javascript
jquery对table做排序操作的实例演示
2017/08/10 jQuery
详解angularjs 学习之 scope作用域
2018/01/15 Javascript
node 文件上传接口的转发的实现
2019/09/23 Javascript
JavaScript Dom 绑定事件操作实例详解
2019/10/02 Javascript
ES6 class类链式继承,实例化及react super(props)原理详解
2020/02/15 Javascript
JavaScript组合设计模式--改进引入案例分析
2020/05/23 Javascript
python开发中range()函数用法实例分析
2015/11/12 Python
python中字符串变二维数组的实例讲解
2018/04/03 Python
python无限生成不重复(字母,数字,字符)组合的方法
2018/12/04 Python
python爬虫之urllib,伪装,超时设置,异常处理的方法
2018/12/19 Python
python 定时器,实现每天凌晨3点执行的方法
2019/02/20 Python
详解Pandas之容易让人混淆的行选择和列选择
2019/07/10 Python
关于python导入模块import与常见的模块详解
2019/08/28 Python
基于MSELoss()与CrossEntropyLoss()的区别详解
2020/01/02 Python
深入CSS3 动画效果的总结详解
2013/05/09 HTML / CSS
突破canvas语法限制 让他支持链式语法
2012/12/24 HTML / CSS
涉外文秘个人求职的自我评价
2013/10/07 职场文书
毕业生就业意向书
2014/04/01 职场文书
为什么 Nginx 比 Apache 更牛逼
2021/03/31 Servers
MySQL优化常用的19种有效方法(推荐!)
2022/03/17 MySQL