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 相关文章推荐
Chrome中模态对话框showModalDialog返回值问题的解决方法
May 25 Javascript
Javascript实现页面跳转的几种方式分享
Oct 26 Javascript
jquery实现简单合拢与展开网页面板的方法
Sep 01 Javascript
js窗口震动小程序分享
Nov 28 Javascript
JavaScript注入漏洞的原理及防范(详解)
Dec 04 Javascript
Angular-Ui-Router+ocLazyLoad动态加载脚本示例
Mar 02 Javascript
微信小程序商城项目之淘宝分类入口(2)
Apr 17 Javascript
详解vue模拟加载更多功能(数据追加)
Jun 23 Javascript
Vue学习之路之登录注册实例代码
Jul 06 Javascript
解决v-for中使用v-if或者v-bind:class失效的问题
Sep 25 Javascript
详解Element-UI中上传的文件前端处理
Aug 07 Javascript
jQuery实现聊天对话框
Feb 08 jQuery
使用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代码
2008/04/09 PHP
ThinkPHP整合百度Ueditor图文教程
2014/10/21 PHP
php使用PDO操作MySQL数据库实例
2014/12/30 PHP
PHP中使用CURL获取页面title例子
2015/01/07 PHP
php中二维数组排序问题方法详解
2015/08/28 PHP
PHP AjaxForm提交图片上传并显示图片源码
2016/11/29 PHP
php如何把表单内容提交到数据库
2019/07/08 PHP
php装饰者模式简单应用案例分析
2019/10/23 PHP
Ajax一统天下之Dojo整合篇
2007/03/24 Javascript
jquery实现标题字体变换的滑动门菜单效果
2015/09/07 Javascript
JavaScript入门系列之知识点总结
2016/03/24 Javascript
浅谈JS原生Ajax,GET和POST
2016/06/08 Javascript
javascript构造函数以及原型对象的理解
2017/01/13 Javascript
Web纯前端“旭日图”实现元素周期表
2017/03/10 Javascript
详解Vue 动态添加模板的几种方法
2017/04/25 Javascript
360提示[高危]使用存在漏洞的JQuery版本的解决方法
2017/10/27 jQuery
vue升级之路之vue-router的使用教程
2018/08/14 Javascript
angularJs select绑定的model取不到值的解决方法
2018/10/08 Javascript
深入讲解Python编程中的字符串
2015/10/14 Python
django实现同一个ip十分钟内只能注册一次的实例
2017/11/03 Python
Python实现读取json文件到excel表
2017/11/18 Python
Python编程实现线性回归和批量梯度下降法代码实例
2018/01/04 Python
Python3.6连接Oracle数据库的方法详解
2018/05/18 Python
python 将json数据提取转化为txt的方法
2018/10/26 Python
Python-Tkinter Text输入内容在界面显示的实例
2019/07/12 Python
wxpython绘制圆角窗体
2019/11/18 Python
基于django micro搭建网站实现加水印功能
2020/05/22 Python
用CSS3将你的设计带入下个高度
2009/08/08 HTML / CSS
德国专业木制品经销商:Holz-Direkt24
2019/12/26 全球购物
建筑人员岗位职责
2013/12/25 职场文书
社区优秀志愿者材料
2014/02/02 职场文书
小学一年级评语大全
2014/04/22 职场文书
护理实习生带教计划
2015/01/16 职场文书
新教师教学工作总结
2015/08/12 职场文书
党员干部学法用法心得体会
2016/01/21 职场文书
写作技巧:如何撰写商业计划书
2019/08/08 职场文书