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

时间: 2024-08-02 21:25:15

Js外部资源按需加载的相关文章

u3d外部资源 打包与加载的问题

被坑了一下午,调bug,u3d外部加载资源一会可以,一会不行,始终找不到问题,最后快下班的时候,重新试了一下,原来是资源打包之前的文件名,和之后的加载资源名必须一样 [MenuItem("Custom Editor/Build AssetBundle From Selection Twice")] static void ExportResourceNoTrack() { // Bring up save panel string path = EditorUtility.SaveFi

按需加载.js .css文件

首先,理解按需加载当你需要用到某个js里面的函数什么鬼,或者某个css里的样式的时候你才开始加载这个文件. 然后是怎样实现的,简单来说就是在js中动态的createElem<script><link>这两种元算--这句话是说给自己的.可以绑定点击事件,滚轮事件(例如图片的懒加载是动态的.) 使用 require.js (一个按需加载的插件)管理.js按需加载,来自http://www.cnblogs.com/chenxizhang/archive/2013/05/16/308194

react-router v4 按需加载的配置方法

在react项目开发中,当访问默认页面时会一次性请求所有的js资源,这会大大影响页面的加载速度和用户体验.所以添加按需加载功能是必要的,以下是配置按需加载的方法: 安装bundle-loader npm install --save-dev bundle-loader 定义Bundle.js import React, { Component } from 'react'; export default class Bundle extends React.Component { constru

前端性能优化之按需加载(React-router+webpack)

一.什么是按需加载 和异步加载script的目的一样(异步加载script的方法),按需加载/代码切割也可以解决首屏加载的速度. 什么时候需要按需加载 如果是大文件,使用按需加载就十分合适.比如一个近1M的全国城市省市县的json文件,在我首屏加载的时候并不需要引入,而是当用户点击选项的时候才加载.如果不点击,则不会加载.就可以缩短首屏http请求的数量以及时间. 如果是小文件,可以不必太在意按需加载.过多的http请求会导致性能问题. 二.实现按需加载的方法 Webpack打包模块工具实现 R

按需加载JS

JavaScript无非就是script标签引入页面,但当项目越来越大的时候,单页面引入N个js显然不行,合并为单个文件减少了请求数,但请求的文件体积却很大.这时候比较合理的做法就是按需加载.按需加载和按需执行JS比较类似,只不过要执行的JS变成了固定的“实现加载JS”的代码.按需加载实现的思路如下: 对滚动条进行事件绑定,假设绑定的函数为function lazyLoadJS(){}; 在函数lazyLoadJS中,按照下面思路实现:选择一个元素作为参照物,当滚动条即将靠近时该元素位置,开始执

iOS和tvOS游戏按需加载资源简介

摘要 与iOS 9和watchOS 2一起,苹果引入了一套新的内容分发API,以便节约设备空间,这就是按需加载资源.通过使用按需加载资源,我们可以将特定的应用程序资源托管在苹果的服务器上,然后在需要的时候进行加载.在这个教程中,我将通过开发一个图片查看应用介绍一下按需加载资源的基本用法. tvOS On Demand Reourse 按需加载 iOS开发 目录[-] 介绍 准备工作 1. 按需加载资源 益处 类别 限制 应用分片 删除按需加载资源 2. 分配和指定Tag 3. 访问按需请求资源

angularjs ocLazyLoad分步加载js文件,angularjs ocLazyLoad按需加载js

用angular有一段时间了,平日里只顾着写代码,没有注意到性能优化的问题,而今有时间,于是捋了捋,讲学习过程记录于此: 问题描述:由于采用angular做了网页的单页面应用,需要一次性在主布局中将所有模块需要引用到的js都引入.对于比较小的项目,这是可行的,但是对于大的项目,一旦js文件较多,在页面首次加载时就引入所有js文件,无疑会延缓页面加载的速度,造成不良额用户体验.那么分布加载(按需加载)就显得很有必要了. <!DOCTYPE html> <html lang="en

背水一战 Windows 10 (11) - 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 资源 CustomResource ResourceDictionary 加载外部的 ResourceDictionary 文件 示例1.演示“CustomResource”相关知识点CustomResourceTest.cs /* * 本例是一个自定义 CustomXamlResourceLoader,用于演示 CustomResource 的使用 */ using Windows.UI.Xaml.Resources;

不依赖jquery的图片LazyLoad按需加载js-echo.js

echo.min.js源码如下: /*! echo.js v1.7.0 | (c) 2015 @toddmotto | https://github.com/toddmotto/echo */ !function(t,e){"function"==typeof define&&define.amd?define(function(){return e(t)}):"object"==typeof exports?module.exports=e:t.e