ol.loader

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,

你可能感兴趣的:(ol.loader)