| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629 | /*! @Name: layui @Description:经典模块化前端 UI 框架 @License:MIT */ ;!function(win){  "use strict";  var doc = document, config = {    modules: {} //记录模块物理路径    ,status: {} //记录模块加载状态    ,timeout: 10 //符合规范的模块请求最长等待秒数    ,event: {} //记录模块自定义事件  }  ,Layui = function(){    this.v = '2.5.7'; //版本号  }  //获取layui所在目录  ,getPath = function(){    var jsPath = doc.currentScript ? doc.currentScript.src : function(){      var js = doc.scripts      ,last = js.length - 1      ,src;      for(var i = last; i > 0; i--){        if(js[i].readyState === 'interactive'){          src = js[i].src;          break;        }      }      return src || js[last].src;    }();    return jsPath.substring(0, jsPath.lastIndexOf('/') + 1);  }()  //异常提示  ,error = function(msg){    win.console && console.error && console.error('Layui hint: ' + msg);  }  ,isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]'  //内置模块  ,modules = {    layer: 'modules/layer' //弹层    ,laydate: 'modules/laydate' //日期    ,laypage: 'modules/laypage' //分页    ,laytpl: 'modules/laytpl' //模板引擎    ,layim: 'modules/layim' //web通讯    ,layedit: 'modules/layedit' //富文本编辑器    ,form: 'modules/form' //表单集    ,upload: 'modules/upload' //上传    ,transfer: 'modules/transfer' //上传    ,tree: 'modules/tree' //树结构    ,table: 'modules/table' //表格    ,element: 'modules/element' //常用元素操作    ,rate: 'modules/rate'  //评分组件    ,colorpicker: 'modules/colorpicker' //颜色选择器    ,slider: 'modules/slider' //滑块    ,carousel: 'modules/carousel' //轮播    ,flow: 'modules/flow' //流加载    ,util: 'modules/util' //工具块    ,code: 'modules/code' //代码修饰器    ,jquery: 'modules/jquery' //DOM库(第三方)        ,mobile: 'modules/mobile' //移动大模块 | 若当前为开发目录,则为移动模块入口,否则为移动模块集合    ,'layui.all': '../layui.all' //PC模块合并版  };  //记录基础数据  Layui.prototype.cache = config;  //定义模块  Layui.prototype.define = function(deps, factory){    var that = this    ,type = typeof deps === 'function'    ,callback = function(){      var setApp = function(app, exports){        layui[app] = exports;        config.status[app] = true;      };      typeof factory === 'function' && factory(function(app, exports){        setApp(app, exports);        config.callback[app] = function(){          factory(setApp);        }      });      return this;    };        type && (      factory = deps,      deps = []    );        if((!layui['layui.all'] && layui['layui.mobile'])){      return callback.call(that);    }    that.use(deps, callback);    return that;  };  //使用特定模块  Layui.prototype.use = function(apps, callback, exports){    var that = this    ,dir = config.dir = config.dir ? config.dir : getPath    ,head = doc.getElementsByTagName('head')[0];    apps = typeof apps === 'string' ? [apps] : apps;        //如果页面已经存在 jQuery 1.7+ 库且所定义的模块依赖 jQuery,则不加载内部 jquery 模块    if(window.jQuery && jQuery.fn.on){      that.each(apps, function(index, item){        if(item === 'jquery'){          apps.splice(index, 1);        }      });      layui.jquery = layui.$ = jQuery;    }        var item = apps[0]    ,timeout = 0;    exports = exports || [];    //静态资源host    config.host = config.host || (dir.match(/\/\/([\s\S]+?)\//)||['//'+ location.host +'/'])[0];        //加载完毕    function onScriptLoad(e, url){      var readyRegExp = navigator.platform === 'PLaySTATION 3' ? /^complete$/ : /^(complete|loaded)$/      if (e.type === 'load' || (readyRegExp.test((e.currentTarget || e.srcElement).readyState))) {        config.modules[item] = url;        head.removeChild(node);        (function poll() {          if(++timeout > config.timeout * 1000 / 4){            return error(item + ' is not a valid module');          };          config.status[item] ? onCallback() : setTimeout(poll, 4);        }());      }    }        //回调    function onCallback(){      exports.push(layui[item]);      apps.length > 1 ?        that.use(apps.slice(1), callback, exports)      : ( typeof callback === 'function' && callback.apply(layui, exports) );    }        //如果引入了完整库(layui.all.js),内置的模块则不必再加载    if(apps.length === 0     || (layui['layui.all'] && modules[item])     || (!layui['layui.all'] && layui['layui.mobile'] && modules[item])    ){      return onCallback(), that;    }        //获取加载的模块 URL    //如果是内置模块,则按照 dir 参数拼接模块路径    //如果是扩展模块,则判断模块路径值是否为 {/} 开头,    //如果路径值是 {/} 开头,则模块路径即为后面紧跟的字符。    //否则,则按照 base 参数拼接模块路径    var url = ( modules[item] ? (dir + 'lay/')       : (/^\{\/\}/.test(that.modules[item]) ? '' : (config.base || ''))    ) + (that.modules[item] || item) + '.js';        url = url.replace(/^\{\/\}/, '');        //如果扩展模块(即:非内置模块)对象已经存在,则不必再加载    if(!config.modules[item] && layui[item]){      config.modules[item] = url; //并记录起该扩展模块的 url    }    //首次加载模块    if(!config.modules[item]){      var node = doc.createElement('script');            node.async = true;      node.charset = 'utf-8';      node.src = url + function(){        var version = config.version === true         ? (config.v || (new Date()).getTime())        : (config.version||'');        return version ? ('?v=' + version) : '';      }();            head.appendChild(node);            if(node.attachEvent && !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && !isOpera){        node.attachEvent('onreadystatechange', function(e){          onScriptLoad(e, url);        });      } else {        node.addEventListener('load', function(e){          onScriptLoad(e, url);        }, false);      }            config.modules[item] = url;    } else { //缓存      (function poll() {        if(++timeout > config.timeout * 1000 / 4){          return error(item + ' is not a valid module');        };        (typeof config.modules[item] === 'string' && config.status[item])         ? onCallback()         : setTimeout(poll, 4);      }());    }        return that;  };  //获取节点的style属性值  Layui.prototype.getStyle = function(node, name){    var style = node.currentStyle ? node.currentStyle : win.getComputedStyle(node, null);    return style[style.getPropertyValue ? 'getPropertyValue' : 'getAttribute'](name);  };  //css外部加载器  Layui.prototype.link = function(href, fn, cssname){    var that = this    ,link = doc.createElement('link')    ,head = doc.getElementsByTagName('head')[0];        if(typeof fn === 'string') cssname = fn;        var app = (cssname || href).replace(/\.|\//g, '')    ,id = link.id = 'layuicss-'+app    ,timeout = 0;        link.rel = 'stylesheet';    link.href = href + (config.debug ? '?v='+new Date().getTime() : '');    link.media = 'all';        if(!doc.getElementById(id)){      head.appendChild(link);    }    if(typeof fn !== 'function') return that;        //轮询css是否加载完毕    (function poll() {      if(++timeout > config.timeout * 1000 / 100){        return error(href + ' timeout');      };      parseInt(that.getStyle(doc.getElementById(id), 'width')) === 1989 ? function(){        fn();      }() : setTimeout(poll, 100);    }());        return that;  };    //存储模块的回调  config.callback = {};    //重新执行模块的工厂函数  Layui.prototype.factory = function(modName){    if(layui[modName]){      return typeof config.callback[modName] === 'function'         ? config.callback[modName]      : null;    }  };  //css内部加载器  Layui.prototype.addcss = function(firename, fn, cssname){    return layui.link(config.dir + 'css/' + firename, fn, cssname);  };  //图片预加载  Layui.prototype.img = function(url, callback, error) {       var img = new Image();    img.src = url;     if(img.complete){      return callback(img);    }    img.onload = function(){      img.onload = null;      typeof callback === 'function' && callback(img);    };    img.onerror = function(e){      img.onerror = null;      typeof error === 'function' && error(e);    };    };  //全局配置  Layui.prototype.config = function(options){    options = options || {};    for(var key in options){      config[key] = options[key];    }    return this;  };  //记录全部模块  Layui.prototype.modules = function(){    var clone = {};    for(var o in modules){      clone[o] = modules[o];    }    return clone;  }();  //拓展模块  Layui.prototype.extend = function(options){    var that = this;    //验证模块是否被占用    options = options || {};    for(var o in options){      if(that[o] || that.modules[o]){        error('\u6A21\u5757\u540D '+ o +' \u5DF2\u88AB\u5360\u7528');      } else {        that.modules[o] = options[o];      }    }    return that;  };  // location.hash 路由解析  Layui.prototype.router = function(hash){    var that = this    ,hash = hash || location.hash    ,data = {      path: []      ,search: {}      ,hash: (hash.match(/[^#](#.*$)/) || [])[1] || ''    };        if(!/^#\//.test(hash)) return data; //禁止非路由规范    hash = hash.replace(/^#\//, '');    data.href = '/' + hash;    hash = hash.replace(/([^#])(#.*$)/, '$1').split('/') || [];        //提取 Hash 结构    that.each(hash, function(index, item){      /^\w+=/.test(item) ? function(){        item = item.split('=');        data.search[item[0]] = item[1];      }() : data.path.push(item);    });        return data;  };    //URL 解析  Layui.prototype.url = function(href){    var that = this    ,data = {      //提取 url 路径      pathname: function(){        var pathname = href          ? function(){            var str = (href.match(/\.[^.]+?\/.+/) || [])[0] || '';            return str.replace(/^[^\/]+/, '').replace(/\?.+/, '');          }()        : location.pathname;        return pathname.replace(/^\//, '').split('/');      }()            //提取 url 参数      ,search: function(){        var obj = {}        ,search = (href           ? function(){            var str = (href.match(/\?.+/) || [])[0] || '';            return str.replace(/\#.+/, '');          }()          : location.search        ).replace(/^\?+/, '').split('&'); //去除 ?,按 & 分割参数                //遍历分割后的参数        that.each(search, function(index, item){          var _index = item.indexOf('=')          ,key = function(){ //提取 key            if(_index < 0){              return item.substr(0, item.length);            } else if(_index === 0){              return false;            } else {              return item.substr(0, _index);            }          }();           //提取 value          if(key){            obj[key] = _index > 0 ? item.substr(_index + 1) : null;          }        });                return obj;      }()            //提取 Hash      ,hash: that.router(function(){        return href           ? ((href.match(/#.+/) || [])[0] || '')        : location.hash;      }())    };        return data;  };  //本地持久性存储  Layui.prototype.data = function(table, settings, storage){    table = table || 'layui';    storage = storage || localStorage;        if(!win.JSON || !win.JSON.parse) return;        //如果settings为null,则删除表    if(settings === null){      return delete storage[table];    }        settings = typeof settings === 'object'       ? settings     : {key: settings};        try{      var data = JSON.parse(storage[table]);    } catch(e){      var data = {};    }        if('value' in settings) data[settings.key] = settings.value;    if(settings.remove) delete data[settings.key];    storage[table] = JSON.stringify(data);        return settings.key ? data[settings.key] : data;  };    //本地会话性存储  Layui.prototype.sessionData = function(table, settings){    return this.data(table, settings, sessionStorage);  }  //设备信息  Layui.prototype.device = function(key){    var agent = navigator.userAgent.toLowerCase()    //获取版本号    ,getVersion = function(label){      var exp = new RegExp(label + '/([^\\s\\_\\-]+)');      label = (agent.match(exp)||[])[1];      return label || false;    }        //返回结果集    ,result = {      os: function(){ //底层操作系统        if(/windows/.test(agent)){          return 'windows';        } else if(/linux/.test(agent)){          return 'linux';        } else if(/iphone|ipod|ipad|ios/.test(agent)){          return 'ios';        } else if(/mac/.test(agent)){          return 'mac';        }       }()      ,ie: function(){ //ie版本        return (!!win.ActiveXObject || "ActiveXObject" in win) ? (          (agent.match(/msie\s(\d+)/) || [])[1] || '11' //由于ie11并没有msie的标识        ) : false;      }()      ,weixin: getVersion('micromessenger')  //是否微信    };        //任意的key    if(key && !result[key]){      result[key] = getVersion(key);    }        //移动设备    result.android = /android/.test(agent);    result.ios = result.os === 'ios';    result.mobile = (result.android || result.ios) ? true : false;        return result;  };  //提示  Layui.prototype.hint = function(){    return {      error: error    }  };  //遍历  Layui.prototype.each = function(obj, fn){    var key    ,that = this;    if(typeof fn !== 'function') return that;    obj = obj || [];    if(obj.constructor === Object){      for(key in obj){        if(fn.call(obj[key], key, obj[key])) break;      }    } else {      for(key = 0; key < obj.length; key++){        if(fn.call(obj[key], key, obj[key])) break;      }    }    return that;  };  //将数组中的对象按其某个成员排序  Layui.prototype.sort = function(obj, key, desc){    var clone = JSON.parse(      JSON.stringify(obj || [])    );        if(!key) return clone;        //如果是数字,按大小排序,如果是非数字,按字典序排序    clone.sort(function(o1, o2){      var isNum = /^-?\d+$/      ,v1 = o1[key]      ,v2 = o2[key];            if(isNum.test(v1)) v1 = parseFloat(v1);      if(isNum.test(v2)) v2 = parseFloat(v2);            if(v1 && !v2){        return 1;      } else if(!v1 && v2){        return -1;      }              if(v1 > v2){        return 1;      } else if (v1 < v2) {        return -1;      } else {        return 0;      }    });    desc && clone.reverse(); //倒序    return clone;  };  //阻止事件冒泡  Layui.prototype.stope = function(thisEvent){    thisEvent = thisEvent || win.event;    try { thisEvent.stopPropagation() } catch(e){      thisEvent.cancelBubble = true;    }  };  //自定义模块事件  Layui.prototype.onevent = function(modName, events, callback){    if(typeof modName !== 'string'     || typeof callback !== 'function') return this;    return Layui.event(modName, events, null, callback);  };  //执行自定义模块事件  Layui.prototype.event = Layui.event = function(modName, events, params, fn){    var that = this    ,result = null    ,filter = (events || '').match(/\((.*)\)$/)||[] //提取事件过滤器字符结构,如:select(xxx)    ,eventName = (modName + '.'+ events).replace(filter[0], '') //获取事件名称,如:form.select    ,filterName = filter[1] || '' //获取过滤器名称,,如:xxx    ,callback = function(_, item){      var res = item && item.call(that, params);      res === false && result === null && (result = false);    };        //如果参数传入特定字符,则执行移除事件    if(params === 'LAYUI-EVENT-REMOVE'){      delete (that.cache.event[eventName] || {})[filterName];      return that;    }        //添加事件    if(fn){      config.event[eventName] = config.event[eventName] || {};      //这里不再对多次事件监听做支持,避免更多麻烦      //config.event[eventName][filterName] ? config.event[eventName][filterName].push(fn) :       config.event[eventName][filterName] = [fn];      return this;    }        //执行事件回调    layui.each(config.event[eventName], function(key, item){      //执行当前模块的全部事件      if(filterName === '{*}'){        layui.each(item, callback);        return;      }            //执行指定事件      key === '' && layui.each(item, callback);      (filterName && key === filterName) && layui.each(item, callback);    });        return result;  };    //新增模块事件  Layui.prototype.on = function(events, modName, callback){    var that = this;    return that.onevent.call(that, modName, events, callback);  }    //移除模块事件  Layui.prototype.off = function(events, modName){    var that = this;    return that.event.call(that, modName, events, 'LAYUI-EVENT-REMOVE');  };  win.layui = new Layui();  }(window);
 |