diff --git a/src/layui.js b/src/layui.js index 54df65d3..2e6b422a 100644 --- a/src/layui.js +++ b/src/layui.js @@ -3,7 +3,7 @@ * Classic modular front-end UI library * MIT Licensed */ - + ;!function(win){ "use strict"; @@ -16,9 +16,9 @@ }; var Layui = function(){ - this.v = '2.8.18'; // Layui 版本号 + this.v = '2.9.0-beta.1'; // Layui 版本号 }; - + // 识别预先可能定义的指定全局对象 var GLOBAL = win.LAYUI_GLOBAL || {}; @@ -36,7 +36,7 @@ } return src || js[last].src; }(); - + return config.dir = GLOBAL.dir || jsPath.substring(0, jsPath.lastIndexOf('/') + 1); }(); @@ -71,7 +71,7 @@ util: 'util', // 工具块 code: 'code', // 代码修饰器 jquery: 'jquery', // DOM 库(第三方) - + all: 'all', 'layui.all': 'layui.all' // 聚合标识(功能性的,非真实模块) }; @@ -96,12 +96,12 @@ }); return this; }; - + type && ( factory = deps, deps = [] ); - + that.use(deps, callback, null, 'define'); return that; }; @@ -115,15 +115,15 @@ apps = function(){ if(typeof apps === 'string'){ return [apps]; - } + } // 当第一个参数为 function 时,则自动加载所有内置模块,且执行的回调即为该 function 参数; else if(typeof apps === 'function'){ callback = apps; return ['all']; - } + } return apps; }(); - + // 如果页面已经存在 jQuery 1.7+ 库且所定义的模块依赖 jQuery,则不加载内部 jquery 模块 if(win.jQuery && jQuery.fn.on){ that.each(apps, function(index, item){ @@ -133,7 +133,7 @@ }); layui.jquery = layui.$ = jQuery; } - + var item = apps[0]; var timeout = 0; @@ -141,7 +141,7 @@ // 静态资源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)$/ @@ -156,7 +156,7 @@ }()); } } - + // 回调 function onCallback(){ exports.push(layui[item]); @@ -172,12 +172,12 @@ callback.apply(layui, exports); }() ); } - + // 如果引入了聚合板,内置的模块则不必重复加载 if( apps.length === 0 || (layui['layui.all'] && modules[item]) ){ return onCallback(), that; } - + /* * 获取加载的模块 URL * 如果是内置模块,则按照 dir 参数拼接模块路径 @@ -185,12 +185,12 @@ * 如果路径值是 {/} 开头,则模块路径即为后面紧跟的字符。 * 否则,则按照 base 参数拼接模块路径 */ - - var url = ( modules[item] ? (dir + 'modules/') + + var url = ( modules[item] ? (dir + 'modules/') : (/^\{\/\}/.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 @@ -199,18 +199,18 @@ // 首次加载模块 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 + 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); @@ -220,19 +220,19 @@ 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', 'error'); } - (typeof config.modules[item] === 'string' && config.status[item]) - ? onCallback() + (typeof config.modules[item] === 'string' && config.status[item]) + ? onCallback() : setTimeout(poll, 4); }()); } - + return that; }; @@ -264,35 +264,35 @@ var that = this; var head = doc.getElementsByTagName('head')[0]; var link = doc.createElement('link'); - + if(typeof fn === 'string') cssname = fn; - + var app = (cssname || href).replace(/\.|\//g, ''); var id = 'layuicss-'+ app; var STAUTS_NAME = 'creating'; var timeout = 0; - + link.href = href + (config.debug ? '?v='+new Date().getTime() : ''); link.rel = 'stylesheet'; link.id = id; link.media = 'all'; - + if(!doc.getElementById(id)){ head.appendChild(link); } - + if(typeof fn !== 'function') return that; - + // 轮询 css 是否加载完毕 (function poll(status) { var delay = 100; var getLinkElem = doc.getElementById(id); // 获取动态插入的 link 元素 - + // 如果轮询超过指定秒数,则视为请求文件失败或 css 文件不符合规范 if(++timeout > config.timeout * 1000 / delay){ return error(href + ' timeout'); } - + // css 加载就绪 if(parseInt(that.getStyle(getLinkElem, 'width')) === 1989){ // 如果参数来自于初始轮询(即未加载就绪时的),则移除 link 标签状态 @@ -306,7 +306,7 @@ }, delay); } }()); - + // 轮询css是否加载完毕 /* (function poll() { @@ -318,31 +318,31 @@ }() : setTimeout(poll, 100); }()); */ - + return that; }; - + // css 内部加载器 Layui.prototype.addcss = function(firename, fn, cssname){ return layui.link(config.dir + 'css/' + firename, fn, cssname); }; - + // 存储模块的回调 config.callback = {}; - + // 重新执行模块的工厂函数 Layui.prototype.factory = function(modName){ if(layui[modName]){ - return typeof config.callback[modName] === 'function' + return typeof config.callback[modName] === 'function' ? config.callback[modName] : null; } }; // 图片预加载 - Layui.prototype.img = function(url, callback, error) { + Layui.prototype.img = function(url, callback, error) { var img = new Image(); - img.src = url; + img.src = url; if(img.complete){ return callback(img); } @@ -353,7 +353,7 @@ img.onerror = function(e){ img.onerror = null; typeof error === 'function' && error(e); - }; + }; }; // 全局配置 @@ -400,13 +400,13 @@ 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(){ @@ -414,10 +414,10 @@ data.search[item[0]] = item[1]; }() : data.path.push(item); }); - + return data; }; - + // URL 解析 Layui.prototype.url = function(href){ var that = this; @@ -432,18 +432,18 @@ : location.pathname; return pathname.replace(/^\//, '').split('/'); }(), - + // 提取 url 参数 search: function(){ var obj = {}; - var search = (href + var 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('=') @@ -455,24 +455,24 @@ } 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 + return href ? ((href.match(/#.+/) || [])[0] || '/') : location.hash; }()) }; - + return data; }; @@ -480,31 +480,31 @@ 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 + + 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); @@ -520,7 +520,7 @@ label = (agent.match(exp)||[])[1]; return label || false; }; - + // 返回结果集 var result = { os: function(){ // 底层操作系统 @@ -532,7 +532,7 @@ return 'ios'; } else if(/mac/.test(agent)){ return 'mac'; - } + } }(), ie: function(){ // ie 版本 return (!!win.ActiveXObject || "ActiveXObject" in win) ? ( @@ -541,17 +541,17 @@ }(), 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); - + return result; }; @@ -561,33 +561,33 @@ error: error }; }; - + // typeof 类型细分 -> string/number/boolean/undefined/null、object/array/function/… Layui.prototype._typeof = Layui.prototype.type = function(operand){ if(operand === null) return String(operand); - + // 细分引用类型 return (typeof operand === 'object' || typeof operand === 'function') ? function(){ var type = Object.prototype.toString.call(operand).match(/\s(.+)\]$/) || []; // 匹配类型字符 var classType = 'Function|Array|Date|RegExp|Object|Error|Symbol'; // 常见类型字符 - + type = type[1] || 'Object'; - + // 除匹配到的类型外,其他对象均返回 object - return new RegExp('\\b('+ classType + ')\\b').test(type) - ? type.toLowerCase() + return new RegExp('\\b('+ classType + ')\\b').test(type) + ? type.toLowerCase() : 'object'; }() : typeof operand; }; - + // 对象是否具备数组结构(此处为兼容 jQuery 对象) Layui.prototype._isArray = Layui.prototype.isArray = function(obj){ var that = this; var len; var type = that.type(obj); - + if(!obj || (typeof obj !== 'object') || obj === win) return false; - + len = 'length' in obj && obj.length; // 兼容 ie return type === 'array' || len === 0 || ( typeof len === 'number' && len > 0 && (len - 1) in obj // 兼容 jQuery 对象 @@ -601,10 +601,10 @@ var callFn = function(key, obj){ // 回调 return fn.call(obj[key], key, obj[key]) }; - + if(typeof fn !== 'function') return that; obj = obj || []; - + // 优先处理数组结构 if(that.isArray(obj)){ for(key = 0; key < obj.length; key++){ @@ -615,7 +615,7 @@ if(callFn(key, obj)) break; } } - + return that; }; @@ -632,12 +632,12 @@ } else if(typeof arr !== 'object'){ // 若 arr 非对象 return [clone]; } - + // 开始排序 clone.sort(function(o1, o2){ var v1 = o1[key]; var v2 = o2[key]; - + /* * 特殊数据 * 若比较的成员均非对象 @@ -679,11 +679,11 @@ return v1 - v2; } } - + /** * 字典序排序 */ - + // 若为非数字比较 if(!isNum[0] && !isNum[1]){ // 字典序比较 @@ -695,7 +695,7 @@ return 0; } } - + // 若为混合比较 if(isNum[0] || !isNum[1]){ // 数字 vs 非数字 return -1; @@ -716,13 +716,13 @@ thisEvent.cancelBubble = true; } }; - + // 字符常理 var EV_REMOVE = 'LAYUI-EVENT-REMOVE'; // 自定义模块事件 Layui.prototype.onevent = function(modName, events, callback){ - if(typeof modName !== 'string' + if(typeof modName !== 'string' || typeof callback !== 'function') return this; return Layui.event(modName, events, null, callback); @@ -739,13 +739,13 @@ var res = item && item.call(that, params); res === false && result === null && (result = false); }; - + // 如果参数传入特定字符,则执行移除事件 if(params === EV_REMOVE){ delete (that.cache.event[eventName] || {})[filterName]; return that; } - + // 添加事件 if(fn){ config.event[eventName] = config.event[eventName] || {}; @@ -760,7 +760,7 @@ } return this; } - + // 执行事件回调 layui.each(config.event[eventName], function(key, item){ // 执行当前模块的全部事件 @@ -768,21 +768,21 @@ 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;