ol.loader结构:
<!-- lang: js -->
var index=0;
ol.loader={
domCompleted:false,
_excute:false,
mods:{},
_queue:{},
xhr:function(){}
style:{
_style:function(options){}
load:function(options,callback){}
},
script:{
_script:function(options,callback){}
_scriptOnload:
load:function(options,callback){}
insert:function(mod,callback){}
},
ready:function(_function){}
setDomCallback:{
Queues:[],
Run:function(){},
DOMContentLoaded:function(){},
ready:function(){},
bindReady:function(){},
callBack:function(fun){}
}
add:function(modName,requireLibs){},
remove:function(modName){},
load:function(mods,options){_load()}
_load:function(mods,options){
this._css_queque={};
this._js_queque={}
this._wait_js_queque={}
this._operateType=null
this._type={
"js":{
_queue_been_load:function(mod){},
_lazy_load:function(mod){},
_load:function(mod){}
},
"css":{
_queue_been_load:function(mod){},
_lazy_load:function(mod){},
_load:function(mod){}
}
},
this._push=function(mod){},
this._remove=function(mod){},
this._attach=function(mods){},
this._hasNext=function(mods){},
this._get=function(index){},
this._load=function(mod){},
this._success=function(){},
......
}
}
<!-- lang: js -->
/**
公共代码类
Last Edit: 2011-12-16
Version: 0.6
**/
if (!window['ol']) {
window['ol'] = {
debug:true,
isIE:/*@cc_on!@*/0,
isIE6:false,
isIE7:false,
isIE8:false
};
}
/**
* ol.pkg
* 按照指定参数,构造包
* Last Update:2011-4-8
*/
ol.pkg=function(arg1,arg2,arg3){
var context,namespace,method;
if(arguments.length==3)
{
context=arg1;
namespace=arg2;
method=arg3;
}else{
context=window;
namespace=arg1;
method=arg2;
}
if (!namespace|| !namespace.length) {
return null
}
var a = namespace.split(".");
for (var c = context, f = 0; f < a["length"]-1; f++) {
c[a[f]] || (c[a[f]] = {});
c = c[a[f]];
}
c=(c[a[a["length"] - 1]] = method||c[a[a["length"] - 1]]||{});
return c;
};
ol.global = {
LibPath:null,
ContextPath:"",
getScriptPath:function(name){
var path, p, script = document.getElementsByTagName("script");
for (var i = 0; i < script.length; i++) {
p=script[i].src.indexOf(name);
if(p>0)
{
path=script[i].src;
p = path.lastIndexOf("/");
return path.substring(0, p + 1);
}
}
return "";
},
alert: function(msg, title) {
alert(msg);
return true;
},
confirm: function(msg, title) {
return confirm(msg);
}
};
(function(){
var index=0;
ol.loader = {
domCompleted:false,
_excute:false,
mods:{},//常用组件
_queue:{},//已加载组件
xhr: function() {
return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
},
style:{
_style: function(options) {
var head = document.getElementsByTagName("head")[0] || document.documentElement,
link = document.createElement("link"),
links = document.getElementsByTagName("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = options.url;
if (0 < links.length) {
var _last = links[links.length - 1];
_last.parentNode.insertBefore(link, _last.nextSibling);
} else {
head.appendChild(link);
}
return link;
},
load:function(options,callback){
var node=this._style(options);
if(callback)callback.call(node);
}
},
script:{
_script: function(options, callback) {
var head = document.getElementsByTagName("head")[0] || document.documentElement,
script = document.createElement("script");
script.type = "text/javascript";
script.src = options.url;
script.async = !options.depend;
if(options.charset)script.charset = options.charset;
head.appendChild(script);
return script;
},
_scriptOnload:document.createElement('script').readyState ?
function(node, callback) {
var oldCallback = node.onreadystatechange;
node.onreadystatechange = function() {
var rs = node.readyState;
if (rs === 'loaded' || rs === 'complete') {
oldCallback && oldCallback();
if(callback)callback.call(node);
// Handle memory leak in IE
node.onreadystatechange = null;
var head = document.getElementsByTagName("head")[0] || document.documentElement;
if ( head && node.parentNode ) {
head.removeChild(node);
}
}
};
} :
function(node, callback) {
node.addEventListener('load', callback, false);
},
load:function(options,callback){
var script=this._script(options,callback);
this._scriptOnload(script,callback);
},
//即时插入(适合于依赖加载且在dom未完成时候)
/*
* callback可以是Array,string或者直接的function
*/
insert:function(mod,callback){
var _callback=[];
if(mod.onload)
{
_callback.push("(");
_callback.push(mod.onload);
_callback.push(")();");
}
if("object"==typeof(callback))
{
for(var i=0;i<callback.length;i++)
{
if("function"==typeof(callback[i]))
{
_callback.push("(");
_callback.push(callback[i]);
_callback.push(")();");
}else if("string"==typeof(callback[i])){
_callback.push(callback[i]);
}
}
}
var charset='';
if(mod.charset)charset='charset="'+mod.charset+'"';
var id="jsapi_loader"+(index++);
document.write('<script id="'+id+'" loadType="insert" type="text/javascript" src="'+mod.url+'" '+charset+'></s' + 'cript>');
if(_callback.length>0){
if(ol.isIE)
{
var js=document.getElementById(id);
//IE6、IE7 support js.onreadystatechange
js.onreadystatechange = function () {
if (js.readyState == 'complete') {
var script = document.createElement("script");
script.type = "text/javascript";
if (ol.loader._excute) {
script.appendChild(document.createTextNode(_callback.join("")));
} else {
script.text = _callback.join("");
}
js.parentNode.insertBefore(script, js.nextSibling);
}
}
}else{
document.write('<script type="text/javascript">'+_callback.join("")+'</s' + 'cript>');
}
}
}
},
ready:function(_function){
ol.loader.setDomCallback.callBack(_function);
},
//参照jquery
setDomCallback: {
Queues: [],
Run: function() {
var Q = ol.loader.setDomCallback.Queues;
for (var i = 0; i < Q["length"]; i++) Q[i].call(document);
ol.loader.setDomCallback.Queues.length = 0;
},
DOMContentLoaded:function(){
if ( document.addEventListener ) {
document.removeEventListener( "DOMContentLoaded", ol.loader.setDomCallback.DOMContentLoaded, false );
ol.loader.setDomCallback.ready();
} else if ( document.attachEvent ) {
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
if ( document.readyState === "complete" ) {
document.detachEvent( "onreadystatechange", ol.loader.setDomCallback.DOMContentLoaded );
ol.loader.setDomCallback.ready();
}
}
},
ready:function(){
// Make sure that the DOM is not already loaded
if (ol.loader.domCompleted)return;
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
if (!document.body){
setTimeout(ol.loader.setDomCallback.ready, 13 );
return;
}
// Remember that the DOM is ready
ol.loader.domCompleted = true;
ol.loader.setDomCallback.Run();
},
bindReady:function(){
var DOMContentLoaded=ol.loader.setDomCallback.DOMContentLoaded;
var ready=ol.loader.setDomCallback.ready;
// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
ready();
return;
}
// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
window.addEventListener( "load", ready, false );
// If IE event model is used
} else if ( document.attachEvent ) {
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent("onreadystatechange", DOMContentLoaded);
// A fallback to window.onload, that will always work
window.attachEvent( "onload", ready );
// If IE and not a frame
// continually check to see if the document is ready
var toplevel = false;
try {
toplevel = window.frameElement == null;
} catch(e) {}
if ( document.documentElement.doScroll && toplevel ) {
ol.loader.setDomCallback.doScrollCheck();
}
}
},
doScrollCheck:function(){
if (ol.loader.domCompleted) return;
try {
// If IE is used, use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
document.documentElement.doScroll("left");
} catch( error ) {
setTimeout(ol.loader.setDomCallback.doScrollCheck, 1 );
return;
}
// and execute any waiting functions
ol.loader.setDomCallback.ready();
},
//回调函数
callBack: function(fun) {
if(typeof(fun)!="function")return;
var Queues = ol.loader.setDomCallback.Queues;
var Run = ol.loader.setDomCallback.Run;
if(ol.loader.domCompleted)
{
fun.call(document);
return;
}else if (Queues["length"] == 0) {
ol.loader.setDomCallback.bindReady();
}
ol.loader.setDomCallback.Queues["push"](fun);
}
},
add:function(modName,requireLibs){
this.mods[modName]=requireLibs;
},
remove:function(modName){
delete this.mods[modName];
},
/**
** options属性:
** loadType://加载方法;lazy为DomContentLoaded后加载
** onload://加载js后立即执行
** callback://加载js后,在DomContentLoaded后执行
**/
load:function(mods,options){
return new ol.loader._loader(mods,options);
},
/**
** mods(object array[string/object] string) 加载内容
** callback(function) 回调函数
** options(function/object) 配置
** loadType(string) 加载类型[lazy:延迟加载]
**/
_loader:function(mods,options){
var self=this;
this._css_queue={};
this._js_queue={};
this._wait_js_queue=[];//未完成队列(js)
this._operateType=null;//操作类型
this._type={
"js":{
_queue_been_load:function(mod){
//log("been load",mod.mark);
//读取下一元素
var _m=self._js_queue[self._get(0)];
if(_m){
//log("next",_m.mark);
self._load(_m);
}else{
//log("last",mod.mark);
self._success();
}
},
_lazy_load:function(mod){
/*
* 2010-09-26
* 当loadType=lazy和加载的插件集合有依赖关系时,回调函数可能会出错.
* 因为lazy下,最后执行的load不一定会最后完成
*/
//将回调函数传给最后执行的load
/*
* _js_queque队列中是否还有元素,有的话就回调方法为空,传递给下一次。
*/
var _c=self._hasNext()?null:options.callback;
ol.loader.load(mod,_c);
},
/*
* mod:{mark:"jquery",uri: "js/jquery-1.4.2.min.js",type: "js", charset: "utf-8",depend:true}
*/
_load:function(mod){
//log("load",mod.mark);
//下一个元素是否依赖
var _m=self._js_queue[self._get(1)];//?
if(!ol.loader.domCompleted){
self._remove(mod);//从队列this_js_queue:this._css_queue中移除mod元素
//即时回调函数
var _callBack=[];
_callBack.push('ol.loader._queue["'+mod.mark+'"]={status:"complete"};');//string/function
//_callBack.push('log("'+mod.mark+'","insert complete");');//string/function*/
//最后一个元素,执行回调
if(!_m){
if(options.onload){
_callBack.push(options.onload);//响应立即回调
}
if(options.callback){
ol.loader.ready(options.callback);//响应回调
}
}
ol.loader.script.insert(mod,_callBack);
//加载下一个元素
if(_m)self._load(_m);
}else{
self._wait_js_queue.push(mod.mark);
var depend=_m?(options.depend||_m.depend):false;
if(depend)self._remove(_m);
//回调函数
var _callBack=function(){
//log(mod.mark,"complete");
try{
if(mod.onload)mod.onload();
if(mod.callback)mod.callback();
}catch(e){
logger.error("'"+(mod.mark)+"' onload or callback",e);
}
self._remove(mod);
ol.loader._queue[mod.mark]={status:"complete"};
//依赖读取
if(depend){
self._load(_m);
}else{
self._success();
}
};
ol.loader.script.load(mod,_callBack);
}
}
},
"css":{
_queue_been_load:function(mod){},
_lazy_load:function(mod){
ol.loader.load(mod);
},
_load:function(mod){
ol.loader.style.load(mod,function(){
self._remove(mod);
ol.loader._queue[mod.mark]={status:"complete"};
});
}
}
}
//放入序列
this._push=function(mod){
if(!mod.mark)mod.mark=(mod.uri||mod.url);
//log("push",mod.mark);
var _queue=("js"==mod.type?this._js_queue:this._css_queue);
if(_queue[mod.mark])return;
_queue[mod.mark]=mod;
}
//移除序列
this._remove=function(mod){
//log("remove",options.mark);
var _queue=("js"==mod.type?this._js_queue:this._css_queue);
delete _queue[mod.mark];
}
//生成序列
this._attach=function(mods){
if("string"==typeof(mods))
{
mods=ol.loader.mods[mods];
if(!mods)
{
//logger.warn("ol.load",mods+" is undefined!");
return;
}
this._attach(mods);
return;
}else if("[object Array]"==Object.prototype.toString.apply(mods)){
for(var i=0;i<mods.length;i++)
{
this._attach(mods[i]);
}
return;
}//if end
this._push(mods);
}
//是否还有元素
this._hasNext=function(){
for(var k in this._js_queue)
{
return true;
}
return false;
}
//读取队首元素
this._get=function(index){
var i=0;
for(var k in this._js_queue)
{
if(i==index)return k;
i++;
}
return null;
}
this._load=function(mod){//mod:{mark:"jquery",uri: "js/jquery-1.4.2.min.js",type: "js", charset: "utf-8",depend:true}]
mod.type=("js"==mod.type)?"js":"css";
/*
* css和js定义了两套不套的加载方式
* this._operateType={
* _queue_been_load:function(mod){},
_lazy_load:function(mod){},
_load:function(mod){}
},
*/
this._operateType=this._type[mod.type];
//检查全局是否已加载
var u=ol.loader._queue[mod.mark];
if(u)
{
this._remove(mod);
var timer;
var f=function(){
var m=ol.loader._queue[mod.mark];
//log(mod.mark,m.status);
if(m.status=="complete"){
clearInterval(timer);
timer=null;
self._operateType._queue_been_load(mod);
}
};
if(u.status!="complete"){
timer=setInterval(f,50);
}else{
self._operateType._queue_been_load(mod);
}
return;
}
var loadType=mod.loadType||options.loadType;
if(ol.loader.domCompleted)
{
//当dom complete后,lazy方式无效
loadType=null;
}
if("lazy"==loadType)
{
/*
* 如果懒加载,直接从队列中拿掉该obj组件,等待dom 完成后加载。
*/
this._remove(mod);
ol.loader.ready(function(){
self._operateType._lazy_load(mod);
});
return;
}
//外队列设置状态
ol.loader._queue[mod.mark]={status:"active"};
/*
* 如果url为空,取uri,uri如果以http://或者https开头 直接赋给url,否则ol.global.LibPath+uri
* 路径中可以存在..
* 如http://localhost:9090/bbb/public/script/jslib/global/../My97DatePicker/WdatePicker.js
*/
if(!mod.url){
if(mod.uri.substr(0,7)=="http://"||mod.uri.substr(0,8)=="https://")mod.url=mod.uri;
else mod.url=ol.global.LibPath+mod.uri;
}
//log("load",mod.mark);
this._operateType._load(mod);
}
/**
* 检查是否全部加载完成,完成执行回调
* 该方法暂时只会在DomContentLoaded后加载的js才会调用
**/
this._success=function(){
if(self._hasNext())return;
//log("load","finish!");
if(typeof(options.callback)=="function"||typeof(options.onload)=="function"){
for(var i=0;i<self._wait_js_queue.length;i++)
{
if(ol.loader._queue[self._wait_js_queue[i]].status!="complete")
{
logger.info("wait",self._wait_js_queue[i]);
setTimeout(self._success,100);
return;
}
}
//log("onload",options.onload);
if(ol.loader.domCompleted){
if(options.onload){
setTimeout(options.onload,0);
options.onload=null;
}
if(options.callback){
setTimeout(options.callback,0);
options.callback=null;
}
}else{
if(options.onload)options.onload();
if(options.callback)ol.loader.ready(options.callback);
}
}
}
if("function"==typeof(options))
{
options={callback:options};
}else if(!options){
options={};
}
if("[object object]"==Object.prototype.toString.apply(mods))//mods:{}
{
this._load(mods);
return;
}else{
/*
* 1.转化统一格式{mark:"jquery",uri: "js/jquery-1.4.2.min.js",type: "js",charset: "utf-8",depend:true} 放入队列
* 最后以这样的格式塞入队列this._js_queque,_css_queque,
*/
this._attach(mods);//string,Array
/*
* 2.加载CSS JS
*/
//加载css
for(var k in this._css_queue)
{
this._load(this._css_queue[k]);//this._css_queue[k]?
}
//加载js
if(options.depend)
{
//log("depend load",this._get(0));
this._load(this._js_queue[this._get(0)]);
}else{
for(var k in this._js_queue)
{
this._load(this._js_queue[k]);
}
}
}
}
};
})();
(function() {
ol.loader._excute = false;
var root = document.documentElement,
script = document.createElement("script"),
id = "script" + (new Date).getTime();
script.type = "text/javascript";
try {
document.write("<!--[if lte IE 6]><script>ol.isIE6=true;</scr"+"ipt><![endif]--><!--[if IE 7]><script>ol.isIE7=true;</scr"+"ipt><![endif]--><!--[if IE 8]><script>ol.isIE8=true;</scr"+"ipt><![endif]-->");
script.appendChild(document.createTextNode("window." + id + "=1;"));
} catch(e) {}
root.insertBefore(script, root.firstChild);
if (window[id]) {
ol.loader._excute = true;
delete window[id];
}
root.removeChild(script);
})();
var logger={
info:function(method,msg){
if(!ol.debug)return;
if(typeof(console)!="undefined"&&console.log)
{
if(msg)console.log("["+method+"]:"+msg);
else console.log(method);
}
},
warn:function(method,msg){
if(!ol.debug)return;
if(typeof(console)!="undefined"&&console.warn)
{
if(msg)console.warn("["+method+"]:"+msg);
else console.warn(method);
}
},
error:function(method,msg){
if(!ol.debug)return;
if(typeof(console)!="undefined"&&console.error)
{
if(msg)console.error("["+method+"]:"+msg);
else console.error(method);
}
}
};
function log(method,msg)
{
logger.info(method,msg);
}
ol.global.LibPath=ol.global.getScriptPath("jsapi-source.js");
//ol.loader end
ol.loader.ready(function(){
ol.loader.domCompleted=true;
logger.info("Dom","Load Complete!");
});
//绑定包名
ol.pkg("ol.load", ol.loader.load);
ol.pkg("ol.ready", ol.loader.ready);
————–说明——————————————
ol.load(mods,options)
mods:
array:
[{},{}]
[“jquery”,“ajax”]
obj:
{}
string:
“jquery”
options:
当其为Object时,表示参数,
{
loadType:“lazy”/,
callback:function,//响应加载完回调。
onload:function,//响应立即回调
depend:true/false,
}
当其为Function时 表示回调函数
callback和onload不同,一个是加载完回调。一个是响应立即回调
if(options.onload){
_callBack.push(options.onload);//响应立即回调
}
if(options.callback){
ol.loader.ready(options.callback);//响应回调
}
callback可以是Array,string或者直接的function
如果这个里面的depend=true,那就只加载第一个js,其他js不加载。
统一写法:
ol.load(mods,options)
{
mark:string
uri/url:string
type:“js”/“css”,
charset:
depend:true/false,
loadType:
onload:
}
如果url为空,取uri,
uri如果以http://或者https开头 直接赋给url,
否则ol.global.LibPath+uri
判断类型:
typeof
Object.protype.toString.apply(obj)
delete
1.生成序列
转化统一格式 放入队列
this._attach=function(mods){
if("string"==typeof(mods))
{
mods=ol.loader.mods[mods];
if(!mods)
{
//logger.warn("ol.load",mods+" is undefined!");
return;
}
this._attach(mods);
return;
}else if("[object Array]"==Object.prototype.toString.apply(mods)){
for(var i=0;i<mods.length;i++)
{
this._attach(mods[i]);
}
return;
}//if end
this._push(mods);
}
this._push=function(mod){
if(!mod.mark)mod.mark=(mod.uri||mod.url);
//log("push",mod.mark);
var _queue=("js"==mod.type?this._js_queue:this._css_queue);
if(_queue[mod.mark])return;
_queue[mod.mark]=mod;
}
统一转入_js_queque,_css_queque,