Skip to content

Instantly share code, notes, and snippets.

@neesenk
Created December 13, 2011 15:41
Show Gist options
  • Save neesenk/1472579 to your computer and use it in GitHub Desktop.
Save neesenk/1472579 to your computer and use it in GitHub Desktop.
异步加载js, 支持依赖关系
/**
* 异步加载js, 支持依赖关系
* Author: zhiyongLiu <zhiyongliu@tencent.com>
*
* 使用方法: LazyLoader().load('a.js').load('b.js').wait().load('c.js')
* .next()
* .load('d.js').load('e.js').wait().load('f.js');
* c.js 依赖与a.js,b.js, f.js 依赖于d.js,e.js; 这两组js之间没有依赖关系;
* c.js将在a.js和b.js之后加载, f.js将在d.js,e.js之后加载; 两组js加载同时进行;
*/
var LazyLoader = {
head: document.head || document.getElementsByTagName("head")[0] || document.documentElement,
queue: [{offset:0, stack:[{scripts:[], finish:0, callback:null}]}],
callback: function (c, obj, cb) {
obj.finish++;
if (cb)
cb.apply(null, arguments);
if (obj.scripts.length > obj.finish || !obj.callback)
return;
c.stack[c.offset++] = null, obj.callback(), obj.callback = null, obj = c.stack[c.offset];
for (var i = 0; i < obj.scripts.length; i++)
obj.scripts[i]();
},
/**
* 加载一个js文件
* @param String url js文件的路径
* @param Function callback 加载完成后的回调函数
*/
loader: function (url, callback) {
var script = document.createElement("script");
script.async = "async";
script.src = url;
script.onload = script.onreadystatechange = function() {
if (!script.readyState || /loaded|complete/.test(script.readyState))
callback();
};
this.head.insertBefore(script, this.head.firstChild);
},
/**
* 开始一组新的js加载, 新的js可以和前一组js并行加载
*/
next: function () {
this.queue.push({offset:0, stack:[{scripts:[], finish:0, callback:null}]});
return this;
},
/**
* 添加一个js文件到加载队列,满足条件之后再加载
* @param String url js的路径
* @param Function callback 加载完后的回调函数
*/
load: function (url, callback) {
var c = this.queue[this.queue.length - 1], obj = c.stack[c.stack.length - 1], self = this;
var loadfunc = function () { self.loader(url, function () { self.callback(c, obj, callback); }); };
obj.scripts.push(loadfunc);
if (c.offset == c.stack.length - 1) // 当前队列没有依赖,可直接加载
loadfunc();
return this;
},
/**
* 等待依赖的js加载完成
* @param Function callback 依赖加载完后的回调
*/
wait: function (callback) {
var c = this.queue[this.queue.length - 1], obj = c.stack[c.stack.length - 1];
if (obj.scripts.length > obj.finish) {
obj.callback = function () { if (callback) callback(); };
c.stack.push({scripts:[], finish:0, callback:null});
} else if (callback) { // 依赖都满足直接调用
callback();
}
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment