欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

动态脚本元素实现js的异步加载和执行的教程

程序员文章站 2022-10-26 13:18:40
动态脚本元素实现js的异步加载和执行 动态脚本元素实现js的异步加载和执行即指——通过动态创建添加script标签实现外部js的异步加载与执行 该方式的特点 ‘s...

动态脚本元素实现js的异步加载和执行

动态脚本元素实现js的异步加载和执行即指——通过动态创建添加script标签实现外部js的异步加载与执行

该方式的特点

‘script.src = “file1.js”’一旦执行完毕,则马上开始异步加载(下载)外部js文件

文件的下载与运行都不会阻塞页面,即js的下载与运行都是异步的

外部js文件一旦加载完成则立即执行

使用外部js中的代码的时机

请看下面的例子:

    /*外部js文件——demo.js*/
    function test(){
        console.log(100);
    }
    /*引用外部js的本地文件*/
    var script = document.createelement('script');
    script.type = 'text/javascript';
    script.src = 'demo.js';
    document.head.appendchild(script);
    test();//在此使用外部js中的代码

然而你会发现,会报错——test未定义

在对上面代码进行改进

    var script = document.createelement('script');
    script.type = 'text/javascript';
    script.src = 'demo.js';
    document.head.appendchild(script);
    settimeout(function(){
        test();//100
    }, 2000);

这是为什么?

因为‘script.src = ‘demo.js’’执行完毕后,马上异步加载外部js文件,然后后续代码继续正常运行,当运行到‘test()’时,可能外部js文件还未加载完毕(比如在网络不好的情况下…),自然出现test未定义。而延时的目的就是让外部在加载完毕的情况下才使用其中的代码

然而使用定时器来解决这个问题显然是滑稽的,看下面的封装方法

对动态脚本元素的兼容封装

function loadscript(url, callback){
    var script = document.createelement ("script");
    script.type = "text/javascript";
    if (script.readystate){ //ie
        script.onreadystatechange = function(){
            if (script.readystate == "loaded" || script.readystate == "complete"){
                script.onreadystatechange = null;
                callback();
            }
        }
    }else { //others
        script.onload = function(){
            callback();
        }
    }
    script.src = url;
    document.getelementsbytagname("head")[0].appendchild(script);
}

代码解析:

if (script.readystate == “loaded” || script.readystate == “complete”)的依据

ie中的,script元素有一个readystate属性,它的值伴随着下载外部js文件的过程而改变。共有五种取值,如下:

1.uninitialized——初始状态

2.loading——下载开始

3.loaded——下载完成

4.interactive——下载完成但尚不可用

5.complete——所有数据已经准备好

但是readystate的这些取值不一定全部出现。在实际中,我们只需要关注loaded与complete。但是,有时script元素会得到loaded却从不出现complete;有时得到complete,却不出现loaded;有时又有可能全部出现

因此我们需要对上述两种情况做判断

script.onreadystatechange = null的依据

前面说到,有时loaded与complete可能全部出现。将事件置为null,解除事件,以免触发两次

一定要先绑定事件,再执行script.src = url,以免出现‘使用外部js中的代码的时机’中所述的问题

该方式不保证文件的加载执行顺序