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 相关文章推荐
控制台报错object is not a function的解决方法
Aug 24 Javascript
深入了解Node.js中的一些特性
Sep 25 Javascript
在JavaScript中操作数组之map()方法的使用
Jun 09 Javascript
js+html5实现的自由落体运动效果代码
Jan 28 Javascript
Bootstrap入门书籍之(五)导航条、分页导航
Feb 17 Javascript
KnockoutJs快速入门教程
May 16 Javascript
深入理解JS中的Function.prototype.bind()方法
Oct 11 Javascript
在vue.js中抽出公共代码的方法示例
Jun 08 Javascript
利用jquery去掉时光轴头尾部线条的方法实例
Jun 16 jQuery
一个Js文件函数中调用另一个Js文件函数的方法演示
Aug 14 Javascript
JS实现获取自定义属性data值的方法示例
Dec 19 Javascript
JavaScript canvas动画实现时钟效果
Feb 10 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
VFP与其他应用程序的集成
2006/10/09 PHP
用PHP生成静态HTML速度快类库
2007/03/18 PHP
php实现html标签闭合检测与修复方法
2015/07/09 PHP
thinkphp3.2.0 setInc方法 源码全面解析
2018/01/29 PHP
stripos函数知识点实例分享
2019/02/11 PHP
tp5.1 框架路由操作-URL生成实例分析
2020/05/26 PHP
Jquery之美中不足小结
2011/02/16 Javascript
jquery如何实现锚点链接之间的平滑滚动
2013/12/02 Javascript
jQuery中prevAll()方法用法实例
2015/01/08 Javascript
jQuery删除一个元素后淡出效果展示删除过程的方法
2015/03/18 Javascript
JQuery 两种方法解决刚创建的元素遍历不到的问题
2016/04/13 Javascript
Bootstrap安装环境配置教程分享
2016/05/27 Javascript
BootStrap table实现表格行拖拽效果
2018/12/01 Javascript
小程序新版订阅消息模板消息
2019/12/31 Javascript
[01:06] DOTA2英雄背景故事第三期之秩序法则光之守卫
2020/07/07 DOTA
python使用PyGame模块播放声音的方法
2015/05/20 Python
python中的格式化输出用法总结
2016/07/28 Python
对python3标准库httpclient的使用详解
2018/12/18 Python
Python函数装饰器常见使用方法实例详解
2019/03/30 Python
Django-xadmin+rule对象级权限的实现方式
2020/03/30 Python
咖啡为什么会有酸味?你喝到的咖啡為什麼是酸的?
2021/03/17 冲泡冲煮
CSS3的resize属性使用初探
2015/09/27 HTML / CSS
详解HTML5中download属性的应用
2015/08/06 HTML / CSS
美丽的现代设计家具:2Modern
2018/07/26 全球购物
美国渔具店:FishUSA
2019/08/07 全球购物
售后专员岗位职责
2013/12/08 职场文书
文秘人员工作职责
2014/01/31 职场文书
会计岗位职责模板
2014/03/12 职场文书
人力资源管理专业毕业生自荐书
2014/05/25 职场文书
家长学校培训材料
2014/08/20 职场文书
入党自传范文2015
2015/06/26 职场文书
煤矿施工安全协议书
2016/03/22 职场文书
写给消防战士们的一封慰问信
2019/10/07 职场文书
oracle覆盖导入dmp文件的2种方法
2021/05/21 Oracle
试了下Golang实现try catch的方法
2021/07/01 Golang
【海涛dota解说】DCG联赛第一周 LGD VS DH
2022/04/01 DOTA