JS/CSS 消極式載入指令碼

來源:互聯網
上載者:User

來源:http://www.cnblogs.com/snandy/archive/2011/04/30/2033272.html

隨著web app中JS越來越多,有時頁面首次載入時有很多JS並沒有用到。這時為了提高下載速度,提高頁面渲染效率就需要讓這部分暫時不用的JS消極式載入,即只在用到它們的時候再下載。這裡會先實現一個最簡單JS的惰性載入。後續幾篇會逐步加強功能直至一個完整的JS/CSS模組載入庫。這個系列裡我不會實現隊列,即各個JS檔案是並行下載的,只有當多個JS全部下載後才執行回調。當然在第二個系列JS Queue LazyLoad中會實現各個JS檔案順序載入,每個JS檔案下載後都有一次回調機會。這兩種方式有各自的應用情境。

先給出使用介面

LazyLoad.js(
urls // js檔案路徑
fn // 全部載入後回呼函數
scope // 指定回呼函數執行內容
);

 樣本

LazyLoad.js(['a.js','b.js','c.js'], function(){
alert('載入完畢');
});

這個系統會盡全力去載入所有的JS檔案,即當某個檔案不存在或載入失敗它不會就此中斷,仍然會去載入其它的JS檔案。直到所有的模組都載入了一次才去回調。

上一篇完成的JS的按需載入,這篇添加個新方法css,完成對CSS檔案的載入。介面與JS相同,樣本如下

LazyLoad.css(['a.css', 'b.css', 'c.css'], function(){
console.log('css模組載入完畢');
});

上一篇對JS的載入實現是通過script元素,css則是通過link元素。而link元素僅IE6/7/8/9和Opera中支援其onreadystatechange事件,Firefox/Safari/Chrome既不支援onreadystatechange,也不支援onload。這裡取了一個巧使用setTimeout消極式載入。

完整代碼

LazyLoad = function(win){
var list1,
list2,
isIE = /*@cc_on!@*/!1,
doc = win.document,
head = doc.getElementsByTagName('head')[0];

function createEl(type, attrs){
var el = doc.createElement(type),
attr;
for(attr in attrs){
el.setAttribute(attr, attrs[attr]);
}
return el;
}
function jsDone(obj){
list1.shift();
if(!list1.length){
obj.fn.call(obj.scope);
}
}
function cssDone(obj){
list2.shift();
if(!list2.length){
obj.fn.call(obj.scope);
}
}
function js(urls, fn, scope){
var obj = {
scope : scope || win,
fn : fn
};
list1 = [].concat(urls);
for(var i=0,len=urls.length; i<len; i++){
var script = createEl('script', {src: urls[i]});
if(isIE){
script.onreadystatechange = function(){
var readyState = this.readyState;
if (readyState == 'loaded' || readyState == 'complete'){
this.onreadystatechange = null;
jsDone(obj);
}
}
}else{
script.onload = script.onerror = function(){
jsDone(obj);
}
}
head.appendChild(script);
}
}
function css(urls, fn, scope){
var obj = {
scope : scope || win,
fn : fn
};
list2 = [].concat(urls);
for(var i=0,len=urls.length; i<len; i++){
var link = createEl('link', {
href : urls[i],
rel : 'stylesheet',
type : 'text/css'
});
if(isIE){
link.onreadystatechange = function(){
var readyState = this.readyState;
if (readyState == 'loaded' || readyState == 'complete'){
this.onreadystatechange = null;
cssDone(obj);
}
}
}else{
setTimeout(function (){
cssDone(obj);
},50*len);
}
head.appendChild(link);
}
}
return {
js : js,
css : css
};
}(this);

檔案下載:http://files.cnblogs.com/snandy/LazyLoad_0.3.js

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.