Js外部资源按需加载

内容来源:http://hi.baidu.com/begin/item/df02bd79ca8cc0710d0a078a

按需加载js的研究和实现

 加载js的基本原理,就是在DOM里面加载<script>元素,加载这些元素都是异步的过程。所以可以说是无阻塞的加载。
但是如果脚本之间存在依赖的话,就会出现不可预知的错误。根据这个,在加载脚本的时候,需要监听“load”事件,对于IE的特殊性,需要监听“readystatechange”事件。
基于这些,实现两个类,第一个类是,加载单个JS的加载器,第二个类,调用第一个类,实现加载多个js,并可配置,是否是同步加载(存在依赖)。
当然,根据传输方式的不同,可以使用Ajax的方式获取JS的内容,但是,Ajax存在跨域的问题,在此,没有采用。
实现代码如下:
ps. 实现了卸载脚本的方法,但是只能卸载DOM结构,无法实现JS的回收,也就是说浏览器依旧保留原先的脚本。

 

/*
* usage:
   var loader = new JsLoader()
   loader.load("xxx.js");
   loader.onsuccess  = function()
  {
      alert("loaded!");  
}
*/
function JsLoader()
{
    this.load = function(url)
    {
        this.url = url;
        //获取所有的<script>标记
        var ss = document.getElementsByTagName("script");
          
        //判断指定的文件是否已经包含,如果已包含则触发onsuccess事件并返回
        for (i = 0; i < ss.length; i++)
        {
            if (ss[i].src && ss[i].src.indexOf(url) != -1)
            {
                this.onsuccess();
                return;
            }
        }
        //创建script结点,并将其属性设为外联JavaScript文件
        var s = document.createElement("script");
        s.type = "text/javascript";
        s.charset = "utf-8";
        s.src = url;
          
        //获取head结点,并将<script>插入到其中
        var head = document.getElementsByTagName("head")[0];
        head.appendChild(s);
          
        //获取自身的引用
        var self = this;
          
        //对于IE浏览器,使用readystatechange事件判断是否载入成功
        //对于其他浏览器,使用onload事件判断载入是否成功
        s.onload = s.onreadystatechange = function()
        {
            //在此函数中this指针指的是s结点对象,而不是JsLoader实例,
            //所以必须用self来调用onsuccess事件,下同。
            if (this.readyState && this.readyState == "loading")
                return;
            self.onsuccess();
        }
        s.onerror = function()
        {
            head.removeChild(s);
            self.onfailure();
        }
    };
    //定义载入成功事件
    this.onsuccess = function()
    {
    };
      
    //定义失败事件
    this.onfailure = function()
    {
    };
      
    //卸载脚本
    this.removejs = function(filename)
    {
        if (!filename)
        {
            filename = this.url;
        }
        var allsuspects = document.getElementsByTagName("script");
        for (var i = allsuspects.length; i >= 0; i--)
        {
            if (allsuspects[i] && allsuspects[i].getAttribute("src") != null &&
            allsuspects[i].getAttribute("src").indexOf(filename) != -1)
                allsuspects[i].parentNode.removeChild(allsuspects[i]); //remove element by calling parentNode.removeChild()
        }
    }
}
   
/*
*载入多个依赖脚本或不依赖的脚本
* usage:
*  var loaders = new JssProc();
*  loaders.loads(["xx.js","xx1.js"],true);//同步加载
*  loaders.loaded = function()
*  {
*       alert("all loaded!");
*  }
*/
function JssProc()
{
   
    //是否同同步加载
    this.loads = function(urls, isSyn)
    {
        var number = 0;
var self = this;
        if (!isSyn)
        {
            for (var i = 0; i < urls.length; i++)
            {
                var s = new JsLoader()
                s.load(urls[i]);
                s.onsuccess = function()
                {
                    number++;
                    if (number == urls.length)
                    {
                        self.loaded();
                    }
                }
            }
        }
        else
        {
            //递归方式
            var j = 0;
            function load()
            {
                j++;
                if (urls[j])
                {
                    var ss = new JsLoader();
                    ss.load(urls[j]);
ss.onsuccess = load;
                }
else
{
self.loaded();
}
            }
            var s = new JsLoader();
            s.load(urls[j]);
            s.onsuccess = load;
        }
    }
    //全部加载完调用的事件
    this.loaded = function()
    {
      
    }
      
    //卸载多个脚本

/*
* usage:
   var loader = new JsLoader()
   loader.load("xxx.js");
   loader.onsuccess  = function()
  {
      alert("loaded!");  
}
*/
function JsLoader()
{
    this.load = function(url)
    {
        this.url = url;
        //获取所有的<script>标记
        var ss = document.getElementsByTagName("script");
          
        //判断指定的文件是否已经包含,如果已包含则触发onsuccess事件并返回
        for (i = 0; i < ss.length; i++) 
        {
            if (ss[i].src && ss[i].src.indexOf(url) != -1) 
            {
                this.onsuccess();
                return;
            }
        }
        //创建script结点,并将其属性设为外联JavaScript文件
        var s = document.createElement("script");
        s.type = "text/javascript";
        s.charset = "utf-8";
        s.src = url;
          
        //获取head结点,并将<script>插入到其中
        var head = document.getElementsByTagName("head")[0];
        head.appendChild(s);
          
        //获取自身的引用
        var self = this;
          
        //对于IE浏览器,使用readystatechange事件判断是否载入成功
        //对于其他浏览器,使用onload事件判断载入是否成功
        s.onload = s.onreadystatechange = function()
        {
            //在此函数中this指针指的是s结点对象,而不是JsLoader实例,
            //所以必须用self来调用onsuccess事件,下同。
            if (this.readyState && this.readyState == "loading") 
                return;
            self.onsuccess();
        }
        s.onerror = function()
        {
            head.removeChild(s);
            self.onfailure();
        }
    };
    //定义载入成功事件
    this.onsuccess = function()
    {
    };
      
    //定义失败事件
    this.onfailure = function()
    {
    };
      
    //卸载脚本
    this.removejs = function(filename)
    {
        if (!filename) 
        {
            filename = this.url;
        }
        var allsuspects = document.getElementsByTagName("script");
        for (var i = allsuspects.length; i >= 0; i--) 
        {
            if (allsuspects[i] && allsuspects[i].getAttribute("src") != null &&
            allsuspects[i].getAttribute("src").indexOf(filename) != -1) 
                allsuspects[i].parentNode.removeChild(allsuspects[i]); //remove element by calling parentNode.removeChild()
        }
    }
}
   
/*
*载入多个依赖脚本或不依赖的脚本
* usage:
*  var loaders = new JssProc();
*  loaders.loads(["xx.js","xx1.js"],true);//同步加载
*  loaders.loaded = function()
*  {
*       alert("all loaded!"); 
*  }
*/
function JssProc()
{
   
    //是否同同步加载
    this.loads = function(urls, isSyn)
    {
        var number = 0;
var self = this;
        if (!isSyn) 
        {
            for (var i = 0; i < urls.length; i++) 
            {
                var s = new JsLoader()
                s.load(urls[i]);
                s.onsuccess = function()
                {
                    number++;
                    if (number == urls.length) 
                    {
                        self.loaded();
                    }
                }
            }
        }
        else
        {
            //递归方式
            var j = 0;
            function load()
            {
                j++;
                if (urls[j]) 
                {
                    var ss = new JsLoader();
                    ss.load(urls[j]);
ss.onsuccess = load;
                }
else
{
self.loaded();
}
            }
            var s = new JsLoader();
            s.load(urls[j]);
            s.onsuccess = load;
        }
    }
    //全部加载完调用的事件
    this.loaded = function()
    {
      
    }
      
    //卸载多个脚本
    this.unload = function()
    {
        for (var i = 0; i < urls.length; i++) 
        {
            new JsLoader().removejs(urls[j]);
        }
    }

 

 


    this.unload = function()
    {
        for (var i = 0; i < urls.length; i++)
        {
            new JsLoader().removejs(urls[j]);
        }
    }

 

 

推介的网址:http://www.w3cfuns.com/article-1116-1.html

Js外部资源按需加载,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。