From ec3a5278c1a2435585fc7d79c3d88152f20ceca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=AB=E7=83=88=E9=B8=9F?= <31432203+mek1986@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:09:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E9=99=A4=20laydate=20=E7=9A=84?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E9=87=8D=E5=A4=8D=E5=A3=B0=E6=98=8E=20(#1441?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 代码优化 * 恢复 `lay.getStyleRules()` 无效改动 --------- Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com> --- src/modules/laydate.js | 391 ++++++++++++++++++++--------------------- 1 file changed, 195 insertions(+), 196 deletions(-) diff --git a/src/modules/laydate.js b/src/modules/laydate.js index d4ce3126..d72e38d9 100644 --- a/src/modules/laydate.js +++ b/src/modules/laydate.js @@ -5,27 +5,27 @@ var isLayui = window.layui && layui.define, ready = { getPath: (window.lay && lay.getPath) ? lay.getPath : '' - + // 载入 CSS 依赖 ,link: function(href, fn, cssname){ - + // 未设置路径,则不主动加载 css if(!laydate.path) return; - + // 加载 css if(window.lay && lay.layui){ lay.layui.link(laydate.path + href, fn, cssname); } } }; - + // 识别预先可能定义的指定全局对象 var GLOBAL = window.LAYUI_GLOBAL || {}; // 模块名 var MOD_NAME = 'laydate'; var MOD_ID = 'layui-'+ MOD_NAME +'-id' // 已渲染过的索引标记名 - + // 外部调用 var laydate = { v: '5.5.0' // layDate 版本号 @@ -34,14 +34,14 @@ } // 全局配置项 ,index: (window.laydate && window.laydate.v) ? 100000 : 0 ,path: GLOBAL.laydate_dir || ready.getPath - + // 设置全局项 ,set: function(options){ var that = this; that.config = lay.extend({}, that.config, options); return that; } - + // 主体 CSS 等待事件 ,ready: function(callback){ var cssname = 'laydate'; @@ -49,21 +49,21 @@ var path = (isLayui ? 'modules/' : '') + 'laydate.css?v='+ laydate.v + ver; isLayui ? ( - layui['layui.all'] - ? (typeof callback === 'function' && callback()) + layui['layui.all'] + ? (typeof callback === 'function' && callback()) : layui.addcss(path, callback, cssname) ) : ready.link(path, callback, cssname); return this; } }; - + // 操作当前实例 var thisModule = function(){ var that = this; var options = that.config; var id = options.id; - + thisModule.that[id] = that; // 记录当前实例对象 return that.inst = { @@ -80,14 +80,13 @@ }; // 字符常量 - var MOD_NAME = 'laydate'; var ELEM = '.layui-laydate'; var THIS = 'layui-this'; var SHOW = 'layui-show'; var HIDE = 'layui-hide'; var DISABLED = 'laydate-disabled'; var LIMIT_YEAR = [100, 200000]; - + var ELEM_STATIC = 'layui-laydate-static'; var ELEM_LIST = 'layui-laydate-list'; var ELEM_SELECTED = 'laydate-selected'; @@ -121,7 +120,7 @@ }); return that; } - + // 初始化属性 options = lay.extend(that.config, lay.options(elem[0])); // 继承节点上的属性 @@ -139,30 +138,30 @@ // 自增索引 options.index = that.index; - + // 初始化 laydate.ready(function(){ that.init(); }); }; - + // 日期格式字符 var dateType = 'yyyy|y|MM|M|dd|d|HH|H|mm|m|ss|s'; - + // 将日期格式字符转换为数组 thisModule.formatArr = function(format){ return (format || '').match(new RegExp(dateType + '|.', 'g')) || [] }; - + /* 组件操作 */ - + // 是否闰年 Class.isLeapYear = function(year){ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; }; - + // 默认配置 Class.prototype.config = { type: 'date' //控件类型,支持:year/month/date/time/datetime @@ -189,7 +188,7 @@ ,autoConfirm: true //是否自动确认(日期|年份|月份选择器非range下是否自动确认) ,shade: 0 }; - + //多语言 Class.prototype.lang = function(){ var that = this @@ -241,7 +240,7 @@ that.config = lay.extend({}, that.config, options); that.init(); }; - + //初始准备 Class.prototype.init = function(){ var that = this @@ -254,10 +253,10 @@ ,time: 'HH:mm:ss' ,datetime: 'yyyy-MM-dd HH:mm:ss' }; - + options.elem = lay(options.elem); options.eventElem = lay(options.eventElem); - + if(!options.elem[0]) return; layui.type(options.theme) !== 'array' && (options.theme = [options.theme]); @@ -296,18 +295,18 @@ lay(options.range[1]) ]; } - + //若 type 设置非法,则初始化为 date 类型 if(!format[options.type]){ window.console && console.error && console.error('laydate type error:\''+ options.type + '\' is not supported') options.type = 'date'; } - + //根据不同 type,初始化默认 format if(options.format === format.date){ options.format = format[options.type] || format.date; } - + //将日期格式转化成数组 that.format = thisModule.formatArr(options.format); @@ -321,10 +320,10 @@ } //生成正则表达式 - that.EXP_IF = ''; - that.EXP_SPLIT = ''; + that.EXP_IF = ''; + that.EXP_SPLIT = ''; lay.each(that.format, function(i, item){ - var EXP = new RegExp(dateType).test(item) + var EXP = new RegExp(dateType).test(item) ? '\\d{'+ function(){ if(new RegExp(dateType).test(that.format[i === 0 ? i + 1 : i - 1]||'')){ if(/^yyyy|y$/.test(item)) return 4; @@ -333,7 +332,7 @@ if(/^yyyy$/.test(item)) return '1,4'; if(/^y$/.test(item)) return '1,308'; return '1,2'; - }() +'}' + }() +'}' : '\\' + item; that.EXP_IF = that.EXP_IF + EXP; that.EXP_SPLIT = that.EXP_SPLIT + '(' + EXP + ')'; @@ -341,19 +340,19 @@ //验证日期格式正则 that.EXP_IF_ONE = new RegExp('^'+ that.EXP_IF +'$'); //验证单个日期格式 that.EXP_IF = new RegExp('^'+ ( - options.range ? + options.range ? that.EXP_IF + '\\s\\'+ that.rangeStr + '\\s' + that.EXP_IF : that.EXP_IF ) +'$'); that.EXP_SPLIT = new RegExp('^'+ that.EXP_SPLIT +'$', ''); - + //如果不是 input|textarea 元素,则默认采用 click 事件 if(!that.isInput(options.elem[0])){ if(options.trigger === 'focus'){ options.trigger = 'click'; } } - + // 设置唯一 KEY options.elem.attr('lay-key', that.index); options.eventElem.attr('lay-key', that.index); @@ -373,7 +372,7 @@ ,'0-10-1': '国庆' ,'0-12-25': '圣诞' } : {}, options.mark); - + //获取限制内日期 lay.each(['min', 'max'], function(i, item){ var ymd = []; @@ -388,7 +387,7 @@ ,hours: i ? 23 : 0 ,minutes: i ? 59 : 0 ,seconds: i ? 59 : 0 - }).getTime() + }).getTime() ,STAMP = 86400000 //代表一天的毫秒数 ,thisDate = new Date( day ? ( @@ -412,29 +411,29 @@ ,seconds: hms[2] | 0 }; }); - + that.elemID = 'layui-laydate'+ options.elem.attr('lay-key'); - + if(options.show || isStatic) that.render(); isStatic || that.events(); - + //默认赋值 if(options.value && options.isInitValue){ if(layui.type(options.value) === 'date'){ - that.setValue(that.parse(0, that.systemDate(options.value))); + that.setValue(that.parse(0, that.systemDate(options.value))); } else { - that.setValue(options.value); + that.setValue(options.value); } } }; - + //控件主体渲染 Class.prototype.render = function(){ var that = this ,options = that.config ,lang = that.lang() ,isStatic = options.position === 'static' - + //主面板 ,elem = that.elem = lay.elem('div', { id: that.elemID @@ -456,7 +455,7 @@ })() ].join('') }) - + //主区域 ,elemMain = that.elemMain = [] ,elemHeader = that.elemHeader = [] @@ -472,9 +471,9 @@ ,divShortcut = that.shortcut = lay.elem('ul', { "class": ELEM_SHORTCUT }); - + if(options.zIndex) elem.style.zIndex = options.zIndex; - + //单双日历区域 lay.each(new Array(2), function(i){ if(!options.range && i > 0){ @@ -485,7 +484,7 @@ var divHeader = lay.elem('div', { "class": 'layui-laydate-header' }) - + //左右切换 ,headerChild = [function(){ //上一年 var elem = lay.elem('i', { @@ -519,19 +518,19 @@ elem.innerHTML = ''; return elem; }()] - + //日历内容区域 ,divContent = lay.elem('div', { "class": 'layui-laydate-content' }) ,table = lay.elem('table') ,thead = lay.elem('thead'), theadTr = lay.elem('tr'); - + //生成年月选择 lay.each(headerChild, function(i, item){ divHeader.appendChild(item); }); - + //生成表格 thead.appendChild(theadTr); lay.each(new Array(6), function(i){ //表体 @@ -547,19 +546,19 @@ }); table.insertBefore(thead, table.children[0]); //表头 divContent.appendChild(table); - + elemMain[i] = lay.elem('div', { "class": ELEM_MAIN + ' laydate-main-list-'+ i }); - + elemMain[i].appendChild(divHeader); elemMain[i].appendChild(divContent); - + elemHeader.push(headerChild); elemCont.push(divContent); elemTable.push(table); }); - + //生成底部栏 lay(divFooter).html(function(){ var html = [], btns = []; @@ -569,7 +568,7 @@ if(!(!options.range && options.type === 'datetime') || options.fullPanel){ html.push('') } - + lay.each(options.btns, function(i, item){ var title = lang.tools[item] || 'btn'; if(options.range && item === 'now') return; @@ -592,7 +591,7 @@ }()).find('li').on('click', function (event) { var btnSetting = options.shortcuts[this.dataset['index']] || {}; var value = (typeof btnSetting.value === 'function' - ? btnSetting.value() + ? btnSetting.value() : btnSetting.value) || []; if (!layui.isArray(value)) { value = [value]; @@ -658,7 +657,7 @@ elem.appendChild(main); }); options.showBottom && elem.appendChild(divFooter); - + // 生成自定义主题 var style = lay.elem('style'); var styleText = []; @@ -714,30 +713,30 @@ document.body.appendChild(elem) ,that.position() //定位 ); - + var shade = options.shade ? ('
') : ''; elem.insertAdjacentHTML('beforebegin', shade); that.checkDate().calendar(null, 0, 'init'); //初始校验 that.changeEvent(); //日期切换 - + Class.thisElemDate = that.elemID; that.renderAdditional() typeof options.ready === 'function' && options.ready(lay.extend({}, options.dateTime, { month: options.dateTime.month + 1 })); - + that.preview(); }; - + //控件移除 Class.prototype.remove = function(prev){ var that = this ,options = that.config ,elem = lay('#'+ (prev || that.elemID)); if(!elem[0]) return that; - + if(!elem.hasClass(ELEM_STATIC)){ that.checkDate(function(){ elem.remove(); @@ -754,7 +753,7 @@ lay('.' + ELEM_SHADE).remove(); return that; }; - + //定位算法 Class.prototype.position = function(){ var that = this @@ -764,7 +763,7 @@ }); return that; }; - + // 提示 Class.prototype.hint = function(opts){ var that = this; @@ -772,7 +771,7 @@ var div = lay.elem('div', { "class": ELEM_HINT }); - + if(!that.elem) return; // 兼容旧版参数 @@ -783,7 +782,7 @@ content: opts } } - + div.innerHTML = opts.content || ''; lay(that.elem).find('.'+ ELEM_HINT).remove(); that.elem.appendChild(div); @@ -793,7 +792,7 @@ lay(that.elem).find('.'+ ELEM_HINT).remove(); }, 'ms' in opts ? opts.ms : 3000); }; - + //获取递增/减后的年月 Class.prototype.getAsYM = function(Y, M, type){ type ? M-- : M++; @@ -807,7 +806,7 @@ } return [Y, M]; }; - + //系统日期 Class.prototype.systemDate = function(newDate){ var thisDate = newDate || new Date(); @@ -820,7 +819,7 @@ ,seconds: newDate ? newDate.getSeconds() : 0 //秒 } }; - + //日期校验 Class.prototype.checkDate = function(fn){ var that = this @@ -829,7 +828,7 @@ ,lang = that.lang() ,dateTime = options.dateTime = options.dateTime || that.systemDate() ,thisMaxDate, error - + ,elem = options.elem[0] ,valType = that.isInput(elem) ? 'val' : 'html' ,value = function(){ @@ -841,11 +840,11 @@ return vals.join(' ' + that.rangeStr + ' '); } } - return that.isInput(elem) - ? elem.value + return that.isInput(elem) + ? elem.value : (options.position === 'static' ? '' : lay(elem).attr('lay-date')); }() - + //校验日期有效数字 ,checkValid = function(dateTime){ if (!dateTime) { @@ -861,13 +860,13 @@ thisMaxDate = laydate.getEndDate(dateTime.month + 1, dateTime.year); if(dateTime.date > thisMaxDate) dateTime.date = thisMaxDate, error = true; } - + //获得初始化日期值 ,initDate = function(dateTime, value, index){ var startEnd = ['startTime', 'endTime']; value = (value.match(that.EXP_SPLIT) || []).slice(1); index = index || 0; - + if(options.range){ that[startEnd[index]] = that[startEnd[index]] || {}; } @@ -902,7 +901,7 @@ }); checkValid(dateTime); }; - + if(fn === 'limit') { if (options.range) { checkValid(that.rangeLinked ? that.startDate : dateTime); // 校验开始时间 @@ -912,7 +911,7 @@ } return that; } - + value = value || options.value; if(typeof value === 'string'){ value = value.replace(/\s+/g, ' ').replace(/^\s|\s$/g, ''); @@ -925,7 +924,7 @@ var obj = {} ,dateTime = options.dateTime ,EYM = that.getAsYM(dateTime.year, dateTime.month); - + //初始右侧面板的年月 if(options.type === 'year'){ obj.year = dateTime.year + 1; @@ -933,19 +932,19 @@ obj.year = EYM[0]; obj.month = EYM[1]; } - + //初始右侧面板的时间 if(options.type === 'datetime' || options.type === 'time'){ obj.hours = 23; obj.minutes = obj.seconds = 59; } - + return obj; }()); } }; getEndDate(); - + if(typeof value === 'string' && value){ if(that.EXP_IF.test(value)){ //校验日期格式 if(options.range){ @@ -969,13 +968,13 @@ //重置开始日期 options.dateTime = that.systemDate(); delete that.startTime; - + //重置结束日期 delete that.endDate; //删除原有的结束日期 getEndDate(); //并重新获得新的结束日期 delete that.endTime; } - + //从日期范围表单中获取初始值 (function(){ if(that.rangeElem){ @@ -988,7 +987,7 @@ }); } })(); - + // 校验日期有效数字 checkValid(dateTime); if(options.range) checkValid(that.endDate); @@ -999,7 +998,7 @@ options.range ? (that.endDate ? that.parse() : '') : that.parse() ); } - + //如果当前日期不在设定的最大小日期区间,则自动纠正在可选区域 //校验主面板是否在可选日期区间 var minMaxError; @@ -1010,7 +1009,7 @@ dateTime = options.dateTime = lay.extend({}, options.min); minMaxError = true; } - + //校验右侧面板是否在可选日期区间 if(options.range){ if(that.getDateTime(that.endDate) < that.getDateTime(options.min) || that.getDateTime(that.endDate) > that.getDateTime(options.max)){ @@ -1049,7 +1048,7 @@ fn && fn(); return that; }; - + // 公历重要日期与自定义备注 Class.prototype.mark = function(td, YMD){ var that = this @@ -1063,7 +1062,7 @@ } }); mark && td.find('div').html(''+ mark +''); - + return that; }; @@ -1074,7 +1073,7 @@ var type = ['', 'work']; if(layui.type(options.holidays) !== 'array') return that; - + lay.each(options.holidays, function(idx, item) { lay.each(item, function(i, dayStr) { if(dayStr === td.attr('lay-ymd')){ @@ -1087,7 +1086,7 @@ return that; }; - + // 无效日期范围的标记 Class.prototype.limit = function(opts){ opts = opts || {}; @@ -1115,20 +1114,20 @@ return hms; }())).getTime(); //time:是否比较时分秒 }); - + isOut = timestamp.now < timestamp.min || timestamp.now > timestamp.max; opts.elem && opts.elem[isOut ? 'addClass' : 'removeClass'](DISABLED); return isOut; }; - + //当前日期对象 Class.prototype.thisDateTime = function(index){ var that = this ,options = that.config; return index ? that.endDate: options.dateTime; }; - + //日历表 Class.prototype.calendar = function(value, index, type){ index = index ? 1 : 0; @@ -1137,26 +1136,26 @@ ,dateTime = value || that.thisDateTime(index) ,thisDate = new Date(), startWeek, prevMaxDate, thisMaxDate ,lang = that.lang() - + ,isAlone = options.type !== 'date' && options.type !== 'datetime' ,tds = lay(that.table[index]).find('td') ,elemYM = lay(that.elemHeader[index][2]).find('span'); - + if(dateTime.year < LIMIT_YEAR[0]) dateTime.year = LIMIT_YEAR[0], that.hint(lang.invalidDate); if(dateTime.year > LIMIT_YEAR[1]) dateTime.year = LIMIT_YEAR[1], that.hint(lang.invalidDate); - + //记录初始值 if(!that.firstDate){ that.firstDate = lay.extend({}, dateTime); } - + //计算当前月第一天的星期 thisDate.setFullYear(dateTime.year, dateTime.month, 1); startWeek = (thisDate.getDay() + (7 - options.weekStart)) % 7; prevMaxDate = laydate.getEndDate(dateTime.month || 12, dateTime.year); //计算上个月的最后一天 thisMaxDate = laydate.getEndDate(dateTime.month + 1, dateTime.year); //计算当前月的最后一天 - + //赋值日 lay.each(tds, function(index_, item){ var YMD = [dateTime.year, dateTime.month], st; @@ -1188,12 +1187,12 @@ }, index: index_ }); - }); - + }); + //同步头部年月 lay(elemYM[0]).attr('lay-ym', dateTime.year + '-' + (dateTime.month + 1)); lay(elemYM[1]).attr('lay-ym', dateTime.year + '-' + (dateTime.month + 1)); - + if(options.lang === 'cn'){ lay(elemYM[0]).attr('lay-type', 'year').html(dateTime.year + ' 年') lay(elemYM[1]).attr('lay-type', 'month').html((dateTime.month + 1) + ' 月'); @@ -1209,21 +1208,21 @@ that.listYM = [ [(that.startDate || options.dateTime).year, (that.startDate || options.dateTime).month + 1] ,[that.endDate.year, that.endDate.month + 1] - ]; + ]; that.list(options.type, 0).list(options.type, 1); - + //同步按钮可点状态 options.type === 'time' ? that.setBtnStatus('时间' ,lay.extend({}, that.systemDate(), that.startTime) ,lay.extend({}, that.systemDate(), that.endTime) ) : that.setBtnStatus(true); - } + } } else { that.listYM = [[dateTime.year, dateTime.month + 1]]; that.list(options.type, 0); } } - + //初始赋值双日历 if(options.range && type === 'init'){ //执行渲染第二个日历 @@ -1237,7 +1236,7 @@ that.calendar(null, 1 - index); } } - + // 通过检测当前有效日期,来设定底部按钮状态 if(!options.range){ var timeParams = ['hours', 'minutes', 'seconds']; @@ -1256,7 +1255,7 @@ time: timeParams }); } - + //同步按钮可点状态 that.setBtnStatus(); @@ -1276,7 +1275,7 @@ ,dateTime = that.rangeLinked ? options.dateTime : [options.dateTime, that.endDate][index] ,lang = that.lang() ,isAlone = options.range && options.type !== 'date' && options.type !== 'datetime' //独立范围选择器 - + ,ul = lay.elem('ul', { "class": ELEM_LIST + ' ' + ({ year: 'laydate-year-list' @@ -1290,13 +1289,13 @@ ,haveList = lay(elemCont).find('.'+ ELEM_LIST)[0] ,isCN = options.lang === 'cn' ,text = isCN ? '年' : '' - + ,listYM = that.listYM[index] || {} ,hms = ['hours', 'minutes', 'seconds'] ,startEnd = ['startTime', 'endTime'][index]; if(listYM[0] < 1) listYM[0] = 1; - + //生成年列表 if(type === 'year'){ var yearNum, startY = yearNum = listYM[0] - 7; @@ -1337,7 +1336,7 @@ lay(elemYM[isCN ? 0 : 1]).attr('lay-ym', (yearNum - 8) + '-' + listYM[1]) .html((startY + text) + ' - ' + (yearNum - 1 + text)); } - + //生成月列表 else if(type === 'month'){ lay.each(new Array(12), function(i){ @@ -1372,8 +1371,8 @@ lay(elemYM[isCN ? 0 : 1]).attr('lay-ym', listYM[0] + '-' + listYM[1]) .html(listYM[0] + text); - } - + } + //生成时间列表 else if(type === 'time'){ //检测时分秒状态是否在有效日期时间范围内 @@ -1394,8 +1393,8 @@ }][i], index: index, time: [ - ['hours'], - ['hours', 'minutes'], + ['hours'], + ['hours', 'minutes'], ['hours', 'minutes', 'seconds'] ][i] }); @@ -1410,7 +1409,7 @@ }); } }; - + //初始化时间对象 if(options.range){ if(!that[startEnd]){ @@ -1419,7 +1418,7 @@ } else { that[startEnd] = dateTime; } - + //生成时分秒 lay.each([24, 60, 60], function(i, item){ var li = lay.elem('li'), childUL = [''+ lang.time[i] +'