打造自己的js库1 -- 脚本动态加载

来源:互联网 发布:jsp 收费系统 源码 编辑:程序博客网 时间:2024/05/01 09:17

外部脚本加载方式中最常用的就是用js语句动态生成script标签并指定src值。这种方式基本上可以兼容所有浏览器,但真正的问题是出在如何指定callback上面。

我们还是来看看ie,在我的测试当中,IE7以下都不支持script标签的onload事件,取而代之的是onreadystatechange事件,并且此事件有个特别的地方,即使ie下,onreadystatechange 的调用 并不是紧紧跟在脚本执行或者失败之后, 而是有一点点延迟,尤其是当有这个请求有缓存的时候。而有可能这一点点延迟的时候就有另一个脚本回调进来了,因此会出现意想不到的问题,这里的解决方案是使用script标签的event 和 for属性。

event 指定一个事件,for属性指定一个id,这样当触发这个事件的时候,script标签就会加载,而最重要的这个事件会发生在script加载完毕之后。所以就有了一下解决方案。


var scriptTag = document.createElement("script");scriptTag.event = "onclick";scriptTag.src = "js/temp1.js";scriptTag.id = scriptTag.htmlFor = "sc1";document.body.appendChild(scriptTag); scriptTag.onreadystatechange = function() {  if ( /loaded|complete/.test( scriptTag.readyState ) ) {    try {    scriptTag.onclick();    } catch( e ) {}    alert();  }};

但这里是仅仅针对了ie做出了对策,同样的,我们可以继而针对所有浏览器做出对策,代码如下:

var addScript = function(setting, callback){var src = setting["src"],//默认60s超时timeout = setting["timeout"] || 60000,parentNode = setting["parentNode"] || document.body,//是否加载完成done = false,handle,//判断是否是老的ieisOldIE = !!document.attachEvent && !(window.opera && toString.call(window.opera) == '[object Opera]');var getRandId = function(){return 'as_' + parseInt(Math.random()*100);}var scriptTag = document.createElement("script");scriptTag.src = src;if( isOldIE ) {scriptTag.event = "onclick";scriptTag.id = scriptTag.htmlFor = "sc1";}parentNode.appendChild(scriptTag); handle = window.setTimeout(function(){done = true;throw new Error("timeout : " + src);scriptTag.parentNode.removeChild(scriptTag);},timeout);scriptTag.onload = scriptTag.onreadystatechange = function() {if ( isOldIE && /loaded|complete/.test(scriptTag.readyState) ) {    try {    scriptTag.onclick();    } catch( e ) {}}clearTimeout(handle);scriptTag.onload = null;scriptTag.onreadystatechange = null;//执行回调done = true;callback();};};
熟悉yepnope的同学可能对上述加载方式并不陌生,yepnope正式通过以上的方式来动态的加载js文件。根据以上的理解,也让我们自己实现一个yepnope变得不再困难。


以上内容均为本人原创,转载请著名出处。同时也欢迎各位批评指正。

0 0
原创粉丝点击