PageSourceSearch

https://sppcncmachining.ru/public/static/common/plus/layui/layui.js

js sppcncmachining.ru collected 2026-10-08 16:22:35 UTC 21,291 bytes, 754 lines download raw bytes

1
2/*!
3 * Layui
4 * Classic modular Front-End UI library
5 * MIT Licensed
6 */
7 
8;!function(win){
9  "use strict";
10
11  var doc = win.document, config = {
12    modules: {} //记录模块物理路径
13    ,status: {} //记录模块加载状态
14    ,timeout: 10 //符合规范的模块请求最长等待秒数
15    ,event: {} //记录模块自定义事件
16  }
17
18  ,Layui = function(){
19    this.v = '2.6.8'; // layui 版本号
20  }
21  
22  //识别预先可能定义的指定全局对象
23  ,GLOBAL = win.LAYUI_GLOBAL || {}
24
25  //获取 layui 所在目录
26  ,getPath = function(){
27    var jsPath = doc.currentScript ? doc.currentScript.src : function(){
28      var js = doc.scripts
29      ,last = js.length - 1
30      ,src;
31      for(var i = last; i > 0; i--){
32        if(js[i].readyState === 'interactive'){
33          src = js[i].src;
34          break;
35        }
36      }
37      return src || js[last].src;
38    }();
39    
40    return config.dir = GLOBAL.dir || jsPath.substring(0, jsPath.lastIndexOf('/') + 1);
41  }()
42
43  //异常提示
44  ,error = function(msg, type){
45    type = type || 'log';
46    win.console && console[type] && console[type]('layui error hint: ' + msg);
47  }
48
49  ,isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]'
50
51  //内置模块
52  ,modules = config.builtin = {
53    lay: 'lay' //基础 DOM 操作
54    ,layer: 'layer' //弹层
55    ,laydate: 'laydate' //日期
56    ,laypage: 'laypage' //分页
57    ,laytpl: 'laytpl' //模板引擎
58    ,layedit: 'layedit' //富文本编辑器
59    ,form: 'form' //表单集
60    ,upload: 'upload' //上传
61    ,dropdown: 'dropdown' //下拉菜单
62    ,transfer: 'transfer' //穿梭框
63    ,tree: 'tree' //树结构
64    ,table: 'table' //表格
65    ,element: 'element' //常用元素操作
66    ,rate: 'rate'  //评分组件
67    ,colorpicker: 'colorpicker' //颜色选择器
68    ,slider: 'slider' //滑块
69    ,carousel: 'carousel' //轮播
70    ,flow: 'flow' //流加载
71    ,util: 'util' //工具块
72    ,code: 'code' //代码修饰器
73    ,jquery: 'jquery' //DOM 库(第三方)
74    
75    ,all: 'all'
76    ,'layui.all': 'layui.all' //聚合标识(功能性的,非真实模块)
77  };
78
79  //记录基础数据
80  Layui.prototype.cache = config;
81
82  //定义模块
83  Layui.prototype.define = function(deps, factory){
84    var that = this
85    ,type = typeof deps === 'function'
86    ,callback = function(){
87      var setApp = function(app, exports){
88        layui[app] = exports;
89        config.status[app] = true;
90      };
91      typeof factory === 'function' && factory(function(app, exports){
92        setApp(app, exports);
93        config.callback[app] = function(){
94          factory(setApp);
95        }
96      });
97      return this;
98    };
99    
100    type && (
101      factory = deps,
102      deps = []
103    );
104    
105    that.use(deps, callback, null, 'define');
106    return that;
107  };
108
109  //使用特定模块
110  Layui.prototype.use = function(apps, callback, exports, from){
111    var that = this
112    ,dir = config.dir = config.dir ? config.dir : getPath
113    ,head = doc.getElementsByTagName('head')[0];
114
115    apps = function(){
116      if(typeof apps === 'string'){
117        return [apps];
118      } 
119      //当第一个参数为 function 时,则自动加载所有内置模块,且执行的回调即ä¸
119ºè¯¥ function 参数;
120      else if(typeof apps === 'function'){
121        callback = apps;
122        return ['all'];
123      }      
124      return apps;
125    }();
126    
127    //如果页面已经存在 jQuery 1.7+ 库且所定义的模块依赖 jQuery,则不加载内部 jquery 模块
128    if(win.jQuery && jQuery.fn.on){
129      that.each(apps, function(index, item){
130        if(item === 'jquery'){
131          apps.splice(index, 1);
132        }
133      });
134      layui.jquery = layui.$ = jQuery;
135    }
136    
137    var item = apps[0]
138    ,timeout = 0;
139    exports = exports || [];
140
141    //静态资源host
142    config.host = config.host || (dir.match(/\/\/([\s\S]+?)\//)||['//'+ location.host +'/'])[0];
143    
144    //加载完毕
145    function onScriptLoad(e, url){
146      var readyRegExp = navigator.platform === 'PLaySTATION 3' ? /^complete$/ : /^(complete|loaded)$/
147      if (e.type === 'load' || (readyRegExp.test((e.currentTarget || e.srcElement).readyState))) {
148        config.modules[item] = url;
149        head.removeChild(node);
150        (function poll() {
151          if(++timeout > config.timeout * 1000 / 4){
152            return error(item + ' is not a valid module', 'error');
153          };
154          config.status[item] ? onCallback() : setTimeout(poll, 4);
155        }());
156      }
157    }
158  
159    //回调
160    function onCallback(){
161      exports.push(layui[item]);
162      apps.length > 1 ?
163        that.use(apps.slice(1), callback, exports, from)
164      : ( typeof callback === 'function' && function(){
165        //保证文档加载完毕再执行回调
166        if(layui.jquery && typeof layui.jquery === 'function' && from !== 'define'){
167          return layui.jquery(function(){
168            callback.apply(layui, exports);
169          });
170        }
171        callback.apply(layui, exports);
172      }() );
173    }
174    
175    //如果引入了聚合板,内置的模块则不必重复加载
176    if( apps.length === 0 || (layui['layui.all'] && modules[item]) ){
177      return onCallback(), that;
178    }
179    
180    //获取加载的模块 URL
181    //如果是内置模块,则按照 dir 参数拼接模块路径
182    //如果是扩展模块,则判断模块路径值是否为 {/} 开头,
183    //如果路径值是 {/} 开头,则模块路径即为后面紧跟的字符。
184    //否则,则按照 base 参数拼接模块路径
185    
186    var url = ( modules[item] ? (dir + 'modules/') 
187      : (/^\{\/\}/.test(that.modules[item]) ? '' : (config.base || ''))
188    ) + (that.modules[item] || item) + '.js';
189    url = url.replace(/^\{\/\}/, '');
190    
191    //如果扩展模块(即:非内置模块)对象已经存在,则不必再加载
192    if(!config.modules[item] && layui[item]){
193      config.modules[item] = url; //并记录起该扩展模块的 url
194    }
195
196    //首次加载模块
197    if(!config.modules[item]){
198      var node = doc.createElement('script');
199      
200      node.async = true;
201      node.charset = 'utf-8';
202      node.src = url + function(){
203        var version = config.version === true 
204        ? (config.v || (new Date()).getTime())
205        : (config.version||'');
206        return version ? ('?v=' + version) : '';
207      }();
208      
209      head.appendChild(node);
210      
211      if(node.attachEvent && !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && !isOpera){
212        node.attachEvent('onreadystatechange', function(e){
213          onScriptLoad(e, url);
214        });
215      } else {
216        node.addEventListener('load', function(e){
217          onScriptLoad(e, url);
218        }, false);
219      }
220      
221      config.modules[item] = url;
222    } else { //缓存
223      (function poll() {
224        if(++timeout > config.timeout * 1000 / 4){
225          return error(item + ' is not a valid module', 'error');
226        };
227        (typeof config.modules[item] === 'string' && config.status[item]) 
228        ? onCallback() 
229        : setTimeout(poll, 4);
230      }());
231    }
232    
233    return that;
234  };
235
236  //获取节点的 style 属性值
237  Layui.prototype.getStyle = function(node, name){
238    var style = node.currentStyle ? node.currentStyle : win.getComputedStyle(node, null);
239    return style[style.getPropertyValue ? 'getPropertyValue' : 'getAttribute'](name);
240  };
241
242  //css外部加载器
243  Layui.prototype.link = function(href, fn, cssname){
244    var that = this
245    ,head = doc.getElementsByTagName('head')[0]
246    ,link = doc.createElement('link');
247    
248    if(typeof fn === 'string') cssname = fn;
249    
250    var app = (cssname || href).replace(/\.|\//g, '')
251    ,id = link.id = 'layuicss-'+ app
252    ,STAUTS_NAME = 'creating'
253    ,timeout = 0;
254    
255    link.rel = 'stylesheet';
256    link.href = href + (config.debug ? '?v='+new Date().getTime() : '');
257    link.media = 'all';
258    
259    if(!doc.getElementById(id)){
260      head.appendChild(link);
261    }
262    
263    if(typeof fn !== 'function') return that;
264    
265    //轮询 css 是否加载完毕
266    (function poll(status) {
267      var delay = 100
268      ,getLinkElem = doc.getElementById(id); //获取动态插入的 link 元素
269      
270      //如果轮询超过指定秒数,则视为请求文件失败或 css 文件不符合规范
271      if(++timeout > config.timeout * 1000 / delay){
272        return error(href + ' timeout');
273      };
274      
275      //css 加载就绪
276      if(parseInt(that.getStyle(getLinkElem, 'width')) === 1989){
277        //如果参数来自于初始轮询(即未加载就绪时的),则移除 link 标签状态
278        if(status === STAUTS_NAME) getLinkElem.removeAttribute('lay-status');
279        //如果 link 标签的状态仍为「创建中」,则继续进入轮询,直到状态改变,则执行回调
280        getLinkElem.getAttribute('lay-status') === STAUTS_NAME ? setTimeout(poll, delay) : fn();
281      } else {
282        getLinkElem.setAttribute('lay-status', STAUTS_NAME);
283        setTimeout(function(){
284          poll(STAUTS_NAME);
285        }, delay);
286      }
287    }());
288    
289    //轮询css是否加载完毕
290    /*
291    (function poll() {
292      if(++timeout > config.timeout * 1000 / 100){
293        return error(href + ' timeout');
294      };
295      parseInt(that.getStyle(doc.getElementById(id), 'width')) === 1989 ? function(){
296        fn();
297      }() : setTimeout(poll, 100);
298    }());
299    */
300    
301    return that;
302  };
303  
304  //css 内部加载器
305  Layui.prototype.addcss = function(firename, fn, cssname){
306    return layui.link(config.dir + 'css/' + firename, fn, cssname);
307  };
308  
309  //存储模块的回调
310  config.callback = {};
311  
312  //重新执行模块的工厂函数
313  Layui.prototype.factory = function(modName){
314    if(layui[modName]){
315      return typeof config.callback[modName] === 'function' 
316        ? config.callback[modName]
317      : null;
318    }
319  };
320
321  //图片预加载
322  Layui.prototype.img = function(url, callback, error) {   
323    var img = new Image();
324    img.src = url; 
325    if(img.complete){
326      return callback(img);
327    }
328    img.onload = function(){
329      img.onload = null;
330      typeof callback === 'function' && callback(img);
331    };
332    img.onerror = function(e){
333      img.onerror = null;
334      typeof error === 'function' && error(e);
335    };  
336  };
337
338  //全局配置
339  Layui.prototype.config = function(options){
340    options = options || {};
341    for(var key in options){
342      config[key] = options[key];
343    }
344    return this;
345  };
346
347  //记录全部模块
348  Layui.prototype.modules = function(){
349    var clone = {};
350    for(var o in modules){
351      clone[o] = modules[o];
352    }
353    return clone;
354  }();
355
356  //拓展模块
357  Layui.prototype.extend = function(options){
358    var that = this;
359
360    //验证模块是否被占用
361    options = options || {};
362    for(var o in options){
363      if(that[o] || that.modules[o]){
364        error(o+ ' Module already exists', 'error');
365      } else {
366        that.modules[o] = options[o];
367      }
368    }
369
370    return that;
371  };
372
373  // location.hash 路由解析
374  Layui.prototype.router = function(hash){
375    var that = this
376    ,hash = hash || location.hash
377    ,data = {
378      path: []
379      ,search: {}
380      ,hash: (hash.match(/[^#](#.*$)/) || [])[1] || ''
381    };
382    
383    if(!/^#\//.test(hash)) return data; //禁止非路由规范
384    hash = hash.replace(/^#\//, '');
385    data.href = '/' + hash;
386    hash = hash.replace(/([^#])(#.*$)/, '$1').split('/') || [];
387    
388    //提取 Hash 结构
389    that.each(hash, function(index, item){
390      /^\w+=/.test(item) ? function(){
391        item = item.split('=');
392        data.search[item[0]] = item[1];
393      }() : data.path.push(item);
394    });
395    
396    return data;
397  };
398  
399  //URL 解析
400  Layui.prototype.url = function(href){
401    var that = this
402    ,data = {
403      //提取 url 路径
404      pathname: function(){
405        var pathname = href
406          ? function(){
407            var str = (href.match(/\.[^.]+?\/.+/) || [])[0] || '';
408            return str.replace(/^[^\/]+/, '').replace(/\?.+/, '');
409          }()
410        : location.pathname;
411        return pathname.replace(/^\//, '').split('/');
412      }()
413      
414      //提取 url 参数
415      ,search: function(){
416        var obj = {}
417        ,search = (href 
418          ? function(){
419            var str = (href.match(/\?.+/) || [])[0] || '';
420            return str.replace(/\#.+/, '');
421          }()
422          : location.search
423        ).replace(/^\?+/, '').split('&'); //去除 ?,按 & 分割参数
424        
425        //遍历分割后的参数
426        that.each(search, function(index, item){
427          var _index = item.indexOf('=')
428          ,key = function(){ //提取 key
429            if(_index < 0){
430              return item.substr(0, item.length);
431            } else if(_index === 0){
432              return false;
433            } else {
434              return item.substr(0, _index);
435            }
436          }(); 
437          //提取 value
438          if(key){
439            obj[key] = _index > 0 ? item.substr(_index + 1) : null;
440          }
441        });
442        
443        return obj;
444      }()
445      
446      //提取 Hash
447      ,hash: that.router(function(){
448        return href 
449          ? ((href.match(/#.+/) || [])[0] || '/')
450        : location.hash;
451      }())
452    };
453    
454    return data;
455  };
456
457  //本地持久性存储
458  Layui.prototype.data = function(table, settings, storage){
459    table = table || 'layui';
460    storage = storage || localStorage;
461    
462    if(!win.JSON || !win.JSON.parse) return;
463    
464    //如果settings为null,则删除表
465    if(settings === null){
466      return delete storage[table];
467    }
468    
469    settings = typeof settings === 'object' 
470      ? settings 
471    : {key: settings};
472    
473    try{
474      var data = JSON.parse(storage[table]);
475    } catch(e){
476      var data = {};
477    }
478    
479    if('value' in settings) data[settings.key] = settings.value;
480    if(settings.remove) delete data[settings.key];
481    storage[table] = JSON.stringify(data);
482    
483    return settings.key ? data[settings.key] : data;
484  };
485  
486  //本地会话性存储
487  Layui.prototype.sessionData = function(table, settings){
488    return this.data(table, settings, sessionStorage);
489  }
490
491  //设备信息
492  Layui.prototype.device = function(key){
493    var agent = navigator.userAgent.toLowerCase()
494
495    //获取版本号
496    ,getVersion = function(label){
497      var exp = new RegExp(label + '/([^\\s\\_\\-]+)');
498      label = (agent.match(exp)||[])[1];
499      return label || false;
500    }
501    
502    //返回结果集
503    ,result = {
504      os: function(){ //底层操作系统
505        if(/windows/.test(agent)){
506          return 'windows';
507        } else if(/linux/.test(agent)){
508          return 'linux';
509        } else if(/iphone|ipod|ipad|ios/.test(agent)){
510          return 'ios';
511        } else if(/mac/.test(agent)){
512          return 'mac';
513        } 
514      }()
515      ,ie: function(){ //ie版本
516        return (!!win.ActiveXObject || "ActiveXObject" in win) ? (
517          (agent.match(/msie\s(\d+)/) || [])[1] || '11' //由于ie11并没有msie的标识
518        ) : false;
519      }()
520      ,weixin: getVersion('micromessenger')  //是否微信
521    };
522    
523    //任意的key
524    if(key && !result[key]){
525      result[key] = getVersion(key);
526    }
527    
528    //移动设备
529    result.android = /android/.test(agent);
530    result.ios = result.os === 'ios';
531    result.mobile = (result.android || result.ios) ? true : false;
532    
533    return result;
534  };
535
536  //提示
537  Layui.prototype.hint = function(){
538    return {
539      error: error
540    };
541  };
542  
543  //typeof 类型细分 -> string/number/boolean/undefined/null、object/array/function/…
544  Layui.prototype._typeof = function(operand){
545    if(operand === null) return String(operand);
546    
547    //细分引用类型
548    return (typeof operand === 'object' || typeof operand === 'function') ? function(){
549      var type = Object.prototype.toString.call(operand).match(/\s(.+)\]$/) || [] //匹配类型字符
550      ,classType = 'Function|Array|Date|RegExp|Object|Error|Symbol'; //常见类型字符
551      
552      type = type[1] || 'Object';
553      
554      //除匹配到的类型外,其他对象均返回 object
555      return new RegExp('\\b('+ classType + ')\\b').test(type) 
556        ? type.toLowerCase() 
557      : 'object';
558    }() : typeof operand;
559  };
560  
561  //对象是否具备数组结构(此处为兼容 jQuery 对象)
562  Layui.prototype._isArray = function(obj){
563    var that = this
564    ,len
565    ,type = that._typeof(obj);
566    
567    if(!obj || (typeof obj !== 'object') || obj === win) return false;
568    
569    len = 'length' in obj && obj.length; //兼容 ie
570    return type === 'array' || len === 0 || (
571      typeof len === 'number' && len > 0 && (len - 1) in obj //兼容 jQuery 对象
572    );
573  };
574
575  //遍历
576  Layui.prototype.each = function(obj, fn){
577    var key
578    ,that = this
579    ,callFn = function(key, obj){ //回调
580      return fn.call(obj[key], key, obj[key])
581    };
582    
583    if(typeof fn !== 'function') return that;
584    obj = obj || [];
585    
586    //优先处理数组结构
587    if(that._isArray(obj)){
588      for(key = 0; key < obj.length; key++){
589        if(callFn(key, obj)) break;
590      }
591    } else {
592      for(key in obj){
593        if(callFn(key, obj)) break;
594      }
595    }
596    
597    return that;
598  };
599
600  //将数组中的对象按其某个成员排序
601  Layui.prototype.sort = function(obj, key, desc){
602    var clone = JSON.parse(
603      JSON.stringify(obj || [])
604    );
605    
606    if(!key) return clone;
607    
608    //如果是数字,按大小排序;如果是非数字,则按字典序排序
609    clone.sort(function(o1, o2){
610      var v1 = o1[key]
611      ,v2 = o2[key]
612      ,isNum = [
613        !isNaN(v1)
614        ,!isNaN(v2)
615      ];
616
617      
618      //若为数字比较
619      if(isNum[0] && isNum[1]){
620        if(v1 && (!v2 && v2 !== 0)){ //数字 vs 空
621          return 1;
622        } else if((!v1 && v1 !== 0) && v2){ //空 vs 数字
623          return -1;
624        } else { //数字 vs 数字
625          return v1 - v2;
626        }
627      };
628      
629      /**
630       * 字典序排序
631       */
632       
633      //若为非数字比较
634      if(!isNum[0] && !isNum[1]){
635        //字典序比较
636        if(v1 > v2){
637          return 1;
638        } else if (v1 < v2) {
639          return -1;
640        } else {
641          return 0;
642        }
643      }
644      
645      //若为混合比较
646      if(isNum[0] || !isNum[1]){ //数字 vs 非数字
647        return -1;
648      } else if(!isNum[0] || isNum[1]) { //非数字 vs 数字
649        return 1;
650      }
651      
652      /*
653      //老版本
654      if(v1 && !v2){
655        return 1;
656      } else if(!v1 && v2){
657        return -1;
658      }
659        
660      if(v1 > v2){
661        return 1;
662      } else if (v1 < v2) {
663        return -1;
664      } else {
665        return 0;
666      }
667      */
668      
669    });
670
671    desc && clone.reverse(); //倒序
672    return clone;
673  };
674
675  //阻止事件冒泡
676  Layui.prototype.stope = function(thisEvent){
677    thisEvent = thisEvent || win.event;
678    try { thisEvent.stopPropagation() } catch(e){
679      thisEvent.cancelBubble = true;
680    }
681  };
682  
683  //字符常理
684  var EV_REMOVE = 'LAYUI-EVENT-REMOVE';
685
686  //自定义模块事件
687  Layui.prototype.onevent = function(modName, events, callback){
688    if(typeof modName !== 'string' 
689    || typeof callback !== 'function') return this;
690
691    return Layui.event(modName, events, null, callback);
692  };
693
694  //执行自定义模块事件
695  Layui.prototype.event = Layui.event = function(modName, events, params, fn){
696    var that = this
697    ,result = null
698    ,filter = (events || '').match(/\((.*)\)$/)||[] //提取事件过滤器字符结构,如:select(xxx)
699    ,eventName = (modName + '.'+ events).replace(filter[0], '') //获取事件名称,如:form.select
700    ,filterName = filter[1] || '' //获取过滤器名称,,如:xxx
701    ,callback = function(_, item){
702      var res = item && item.call(that, params);
703      res === false && result === null && (result = false);
704    };
705    
706    //如果参数传入特定字符,则执行移除事件
707    if(params === EV_REMOVE){
708      delete (that.cache.event[eventName] || {})[filterName];
709      return that;
710    }
711    
712    //添加事件
713    if(fn){
714      config.event[eventName] = config.event[eventName] || {};
715
716      //这里不再对重复事件做支持
717      //config.event[eventName][filterName] ? config.event[eventName][filterName].push(fn) : 
718      config.event[eventName][filterName] = [fn];
719      return this;
720    }
721    
722    //执行事件回调
723    layui.each(config.event[eventName], function(key, item){
724      //执行当前模块的全部事件
725      if(filterName === '{*}'){
726        layui.each(item, callback);
727        return;
728      }
729      
730      //执行指定事件
731      key === '' && layui.each(item, callback);
732      (filterName && key === filterName) && layui.each(item, callback);
733    });
734    
735    return result;
736  };
737  
738  //新增模块事件
739  Layui.prototype.on = function(events, modName, callback){
740    var that = this;
741    return that.onevent.call(that, modName, events, callback);
742  }
743  
744  //移除模块事件
745  Layui.prototype.off = function(events, modName){
746    var that = this;
747    return that.event.call(that, modName, events, EV_REMOVE);
748  };
749  
750  //exports layui
751  win.layui = new Layui();
752  
753}(window); //gulp build: layui-footer
754

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.