工作需要,写了一个基于jquery的时间控件,仿win10系统时间控件格式。
目前基本功能都有了,但时间格式只实现少数,但由于结构设计已经充分优化,填充起来非常容易。
这个控件相对网上其他的时间控件,代码少,易阅读,修改拓展方便,也适合新手参考学习。
if (typeof jQuery === 'undefined') { throw 'no jquery'; } (function () { window.UE_CONTROL_IDX = 0; $.fn.GetRect = function () { var r = $(this).get(0).getBoundingClientRect(), t = document.documentElement.clientTop, l = document.documentElement.clientLeft; return { top: r.top - t, bottom: r.bottom - t, left: r.left - l, right: r.right - l } } 'use strict'; window.UEDate || (window.UEDate = { viewTypes: { 's': 'yyyy-MM-ddThh:mm:ss', 't': 'h:m', 'y': 'y年m月', 'd': 'y/M/d/', 'm': 'm月d日', 'f': 'y年m月d日 h:m', 'g': 'y/m/d h:m', 'r': 'Sat, 05 Nov 2005 14:06:25 GMT', 'u': 'yyyy-MM-dd hh:mm:ssZ', 'T': 'h:m:s', 'Y': 'y年m月', 'D': 'y年m月d日', 'M': 'm月d日', 'F': 'y年m月d日 h:m:s', 'G': 'y/m/d h:m:s', 'R': 'Sat, 05 Nov 2005 14:06:25 GMT', 'U': 'y年m月d日 h:m:s', 'v': 'dd/MM/yyyy hh:mm:ss', }, config: { viewType: 'v', 80, height:30, maxWidth: 360, maxHeight: 200, showBorder: true, BorderColor: "#666", BackColor: '#fff', value: null, fullMonth: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], simpleMonth: ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May.', 'Jun.', 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.'], fullWeek: ['Monday', 'Tuesday', 'Wednesday', 'Thurday', 'Friday', 'Saturday', 'Sunday'], simpleWeek: ['Mon.', 'Tue.', 'Wed.', 'Thu.', 'Fri.', 'Sat.', 'Sun.'], style: '' + '<style id="ue_date_Style">' + ' .ue_date_frame {border:none;overflow:hidden;position:absolute;left:0;top:0;font-size:12px;user-select:none;margin: 0;padding: 1px;background-color:#fff;z-index:1;}' + ' .ue_date_content {border: 1px solid #fff;border-radius:2px;outline:none;position: relative;overflow:hidden;background-color:user-select:none; transparent;display: inline-block;float:left;padding:0 1px;height:18px;line-height:16px;}' + ' .ue_date_content:hover {border 1px solid #69c;}' + ' .ue_date_split {border: none;position: relative; overflow:hidden;6px;background-color: transparent;display: inline-block;float:left;padding:0;height:18px;line-height:20px;}' + ' .ue_date_over {border:none;210px; height:18px;overflow:hidden;text-align:center;position:relative;margin:5px 0;}' + ' .ue_date_over div {border:none;height:18px;line-height:18px;20px;text-align:center;border-radius:2px;cursor:pointer;}' + ' .ue_date_left {float:left;}.ue_date_left:hover{border:1px solid #69c;height:16px;line-height:16px;18px;}.ue_date_select {100px !important;display:inline-block;}.ue_date_right {float:right;}.ue_date_right:hover{border:1px solid #9cf;height:16px;line-height:16px;18px;}' + ' .ue_date_year {28px;}.ue_date_month {15px;} .ue_date_day {15px;}.ue_date_hour {15px;} .ue_date_minute {15px;} .ue_date_second {15px;}.ue_date_msec {28px;}' + ' .ue_date_pop {border:1px solid #999;border-radius:3px;210px;height:auto;overflow:hidden;position:absolute;font-size:12px;user-select:none;margin: 0;padding: 3px;background-color:#fff;display:none;z-index:2;}' + ' .ue_date_week {border:none;210px; height:18px;overflow:hidden;}' + ' .ue_date_week div {border:none;height:18px;line-height:18px;30px;text-align:center;border-radius:2px;display:inline-block;}' + ' .ue_date_dates {border:none;210px; height:auto;overflow:hidden;}.ue_date_selected {background:#9cf;}' + ' .ue_date_dates div {border:none;height:18px;line-height:18px;30px;text-align:center;border-radius:2px;display:inline-block;cursor:pointer;}' + ' .ue_date_months{border:none;210px; height:auto;overflow:hidden;display:none;}' + ' .ue_date_months div {border:none;height:18px;line-height:18px;42px;margin:5px;text-align:center;border-radius:2px;display:inline-block;cursor:pointer;}' + ' .ue_date_months div:hover {border:1px solid #69c;height:16px;line-height:16px;40px;}' + ' .ue_date_canhover{} .ue_date_canhover:hover {border:1px solid #69c;height:16px;line-height:16px;28px;}' + ' .ue_date_target {user-select:true;}' + '</style>', }, toFixStr: function (value) { return (value < 10 ? '0' : '') + value; }, getDateFromText: function (t, f) { if (t) { f = f || this.config.viewType; if (f == 'v') { var s = t.split(' '); var l = s[0].split('/'); t = l[2] + '-' + l[1] + '-' + l[0] + ' ' + (s.length > 1 ? s[1] : ''); } else { t = t.replace('T', ' '); } try{ return new Date(t); }catch(e){ return null; } } else { return null; } }, getFmtDate: function (v, f) { f = f || this.viewType; switch (f) { case 's': { } break; case 't': { } break; case 'y': { } break; case 'd': { } break; case 'm': { } break; case 'f': { } break; case 'g': { } break; case 'r': { } break; case 'u': { return v.getFullYear() + '-' + (v.getMonth() + 1) + '-' + v.getDate() + ' ' + v.getHours() + ':' + v.getMinutes() + ':' + v.getSeconds(); } break; case 'v': { return v.getDate() + '/' + (v.getMonth() + 1) + '/' + v.getFullYear() + ' ' + v.getHours() + ':' + v.getMinutes() + ':' + v.getSeconds(); } break; default: { return v.getFullYear() + '-' + (v.getMonth() + 1) + '-' + v.getDate() + ' ' + v.getHours() + ':' + v.getMinutes() + ':' + v.getSeconds(); } break; } }, showCalendar: function () { this.calendarDom = this.calendarDom || $('' + '<div class="ue_date_pop">' + ' <div class="ue_date_over">' + ' <div class="ue_date_left">◂</div>' + ' <div class="ue_date_select">2016年8月</div>' + ' <div class="ue_date_right">▸</div>' + ' </div>' + ' <div class="ue_date_week">' + ' <div>Mon</div><div>Tue</div><div>Wed</div><div>Thu</div><div>Fri</div><div>Sat</div><div>Sun</div>' + ' </div>' + ' <div class="ue_date_dates"></div>' + ' <div class="ue_date_months"></div>' + '</div>').appendTo($('body')); this.calendarDom.show(); this.setCalendarDate(new Date(this.calendarYear, this.calendarMonth, 1, 0, 0, 0, 0)); this.setCalendarPosition(); }, setCalendarPosition: function () { var ww = $(window).width(), wh = $(window).height(), bt = $('body').scrollTop(), bl = $('body').scrollLeft(), cw = this.calendarDom.outerWidth(), ch = this.calendarDom.outerHeight(), tw = this.target.outerWidth(), th = this.target.outerHeight(), rc = this.target.GetRect(); if ((rc.top + th + ch + 5) < wh) { this.calendarDom.css({ top: rc.top + th }); } else { this.calendarDom.css({ top: rc.top - ch }); } if ((rc.left + cw) > ww) { this.calendarDom.css({ left: (ww - cw) }); } else { this.calendarDom.css({ left: rc.left }); } }, setCalendarDate: function (dt) { $(".ue_date_week").show(); $(".ue_date_months").hide(); var y = dt.getFullYear(), m = dt.getMonth(), day = dt.getDay(), maxDay = (m == 1 ? (((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) ? 28 : 29) : (m == 3 || m == 5 || m == 8 || m == 10) ? 30 : 31), cnt = day + maxDay, p = $('.ue_date_dates').html('').show(); for (var i = j = 1; i < cnt; i++) { if (i >= day && j <= maxDay) { var o = $('<div class="ue_date_canhover">' + j + '</div>').appendTo(p); if (j == this.date) { o.addClass('ue_date_selected'); } j++; } else { p.append('<div></div>'); } } $('.ue_date_select').html(this.config.fullMonth[m] + ',' + y); this.calendarYear = dt.getFullYear(); this.calendarMonth = dt.getMonth(); this.bindCalendarEvent('d'); }, setCalendarMonth: function (m) { $(".ue_date_week").hide(); $(".ue_date_dates").hide(); var d = $('.ue_date_months').html('').show(); for (var i = 0; i < 12; i++) { var o = $('<div class="ue_date_canhover">' + this.config.simpleMonth[i] + '</div>').appendTo(d); if (i == this.month) { o.addClass('ue_date_selected'); } } $(".ue_date_select").html(this.calendarYear); this.bindCalendarEvent('m'); }, setCalendarYear: function (y) { var d = $('.ue_date_months').html(''); for (var i = 0; i < 12; i++) { var o = $('<div class="ue_date_canhover">' + (y + i) + '</div>').appendTo(d); if ((y + i) == this.year) { o.addClass('ue_date_selected') } } $(".ue_date_select").html(y + ' - ' + (y + 11)); this.bindCalendarEvent('y'); }, bindCalendarEvent: function (type) { var dt = this; $('.ue_date_left').off('click').on('click', function () { if (type == 'd') { var t = new Date(dt.calendarYear, dt.calendarMonth, 1, 0, 0, 0, 0); t.setMonth(t.getMonth() - 1); dt.setCalendarDate(t); } if (type == 'm') { dt.calendarYear -= 1 $(".ue_date_select").html(dt.calendarYear); } if (type == 'y') { var years = $(".ue_date_select").html().split('-'); var year = parseInt(years[0], 10); dt.setCalendarYear(year - 12); } }); $('.ue_date_right').off('click').on('click', function () { if (type == 'd') { var t = new Date(dt.calendarYear, dt.calendarMonth, 1, 0, 0, 0, 0); t.setMonth(t.getMonth() + 1); dt.setCalendarDate(t); } if (type == 'm') { dt.calendarYear += 1 $(".ue_date_select").html(dt.calendarYear); } if (type == 'y') { var years = $(".ue_date_select").html().split('-'); var year = parseInt(years[0], 10); dt.setCalendarYear(year + 12); } }); $('.ue_date_select').off('click').on('click', function () { if (type == 'd') { dt.setCalendarMonth(); } if (type == 'm') { dt.setCalendarYear(dt.calendarYear - 6); } }); $('.ue_date_canhover').off('click').on('click', function () { if (type == 'd') { var date = parseInt(this.innerHTML, 10); dt.value = new Date(dt.calendarYear, dt.calendarMonth, date, dt.hour, dt.minute, dt.second, 0); dt.setTargetValue(); $('.ue_date_frame').remove(); $('.ue_date_pop').hide(); } if (type == 'm') { arr = dt.config.simpleMonth; for(var i in arr){ if (arr[i] == this.innerHTML) { dt.calendarMonth = i; var t = new Date(dt.calendarYear, i, 1, 0, 0, 0, 0); dt.setCalendarDate(t); } } } if (type == 'y') { dt.calendarYear = parseInt(this.innerHTML, 10); dt.setCalendarMonth(); } }); }, getMaxDate: function () { var y = parseInt(this.frameDom.find('.ue_date_year').val(), 10); var m = parseInt(this.frameDom.find('.ue_date_month').val(), 10); return (m == 2 ? (((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) ? 28 : 29) : (m == 4 || m == 6 || m == 9 || m == 11) ? 30 : 31); }, changeValue: function (part, v) { var t = parseInt(v, 10); this[part] = part == 'month' ? t - 1 : t; this.value = new Date(this.year, this.month, this.date, this.hour, this.minute, this.second, 0); }, bindEvent: function () { var dt = this; this.frameDom.find('input').off('blur').on('blur', function () { var v = this.value, o = $(this), part = o.attr('date_part'), y = dt.value.getFullYear(), m = dt.value.getMonth() + 1; if (isNaN(v) || v < 0 || (part == 'year' && (v < 1900 || v > 2100)) || (part == 'month' && (v < 1 || v > 12)) || (part == 'date' && (v < 1 || v > 31 || (m == 2 ? (((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) ? v > 28 : v > 29) : (m == 4 || m == 6 || m == 9 || m == 11) ? v > 30 : v > 31))) || (part == 'hour' && v > 23) || (part == 'minute' && v > 59) || (part == 'second' && v > 59)) { o.css({ borderColor: '#f00' }).focus(); } else { o.css({ borderColor: '#fff' }); dt.changeValue(part, v); } }).off('focus').on('focus',function () { var o = $(this), part = o.attr('date_part'); if (o.css('borderColor') == 'rgb(255, 255, 255)') { o.css({ borderColor: '#69c' }); } }); $(document).off('keyup').on('keyup', function (e) { e = e || window.event; var t = e.srcElement || e.target; if ($(t).hasClass('ue_date_content')) { e.which = e.which == 13 ? 9 : e.which; dt.keyStatus = 'keyup'; } }).off('keydown').on('keydown', function (e) { e = e || window.event; var obj = document.activeElement; if ($(obj).hasClass('ue_date_content')) { var v = parseInt(obj.value, 10); switch (e.which) { case 38: {//上向键 dt.keyStatus = 'key38down'; var min = $(obj).hasClass('ue_date_year') ? 1900 : $(obj).hasClass('ue_date_month') ? 1 : $(obj).hasClass('ue_date_day') ? 1 : 0; var up = setInterval(function () { if (dt.keyStatus == 'key38down') { if (v > min) { obj.value = dt.toFixStr(v--); } else { clearInterval(up); } } else { clearInterval(up); } }, 100); if (v > min) { obj.value = dt.toFixStr(v -= 1); } } break; case 40: {//下向键 dt.keyStatus = 'key40down'; var max = $(obj).hasClass('ue_date_year') ? 2100 : $(obj).hasClass('ue_date_month') ? 12 : $(obj).hasClass('ue_date_day') ? dt.getMaxDate() : $(obj).hasClass('ue_date_hour') ? 23 : 59; var down = setInterval(function () { if (dt.keyStatus == 'key40down') { if (v < max) { obj.value = dt.toFixStr(v++); } else { clearInterval(down); } } else { clearInterval(down); } }, 100); if (v < max) { obj.value = dt.toFixStr(v += 1); } } break; default: break; } } }).off('click').on('click', function (e) { e = e || window.event; var t = e.srcElement || e.target; var c = $(t).attr('class'); if (!c || c.indexOf('ue_date_') == -1) { dt.setTargetValue(); $('.ue_date_frame').remove(); $('.ue_date_pop').hide(); } }); }, setTargetValue: function () { var v = this.getFmtDate(this.value); this.target.html(v).text(v).val(v); }, setValue: function (o,v) { var v = this.getFmtDate(v, 'u'); tg.html(v).text(v).val(v); }, setSeqByViewType: function () { var idx = this.ue_control_idx; switch (this.viewType) { case 's': { this.split3.html('T'); } break; case 't': { this.yearDom.hide(); this.split1.hide(); this.monthDom.hide(); this.split2.hide(); this.dateDom.hide(); this.split3.hide(); this.split5.hide(); this.secondDom.hide(); } break; case 'y': { this.split2.hide(); this.dateDom.hide(); this.split3.hide(); this.hourDom.hide(); this.split4.hide(); this.minuteDom.hide(); this.split5.hide(); this.secondDom.hide(); } break; case 'd': { this.split3.hide(); this.hourDom.hide(); this.split4.hide(); this.minuteDom.hide(); this.split5.hide(); this.secondDom.hide(); } break; case 'm': { this.yearDom.hide(); this.split1.hide(); this.split3.hide(); this.hourDom.hide(); this.split4.hide(); this.minuteDom.hide(); this.split5.hide(); this.secondDom.hide(); } break; case 'f': { } break; case 'g': { } break; case 'r': { } break; case 'u': { } break; case 'v': { this.dateDom.insertBefore(this.yearDom); this.yearDom.insertBefore(this.split3); this.split1.html('/'); this.split2.html('/'); } break; default: { } break; } }, initView: function () { this.frameDom = $('<div class="ue_date_frame" idx="' + this.idx + '" ></div>').appendTo($('body')); this.yearDom = $('<input class="ue_date_content ue_date_year" date_part="year" idx="' + this.idx + '" />').appendTo(this.frameDom); this.split1 = $('<div class="ue_date_split" idx="' + this.idx + '">-</div>').appendTo(this.frameDom); this.monthDom = $('<input class="ue_date_content ue_date_month" date_part="month" idx="' + this.idx + '" />').appendTo(this.frameDom); this.split2 = $('<div class="ue_date_split" idx="' + this.idx + '">-</div>').appendTo(this.frameDom); this.dateDom = $('<input class="ue_date_content ue_date_day" date_part="date" idx="' + this.idx + '" />').appendTo(this.frameDom); this.split3 = $('<div class="ue_date_split" idx="' + this.idx + '"> </div>').appendTo(this.frameDom); this.hourDom = $('<input class="ue_date_content ue_date_hour" date_part="hour" idx="' + this.idx + '" />').appendTo(this.frameDom); this.split4 = $('<div class="ue_date_split" idx="' + this.idx + '">:</div>').appendTo(this.frameDom); this.minuteDom = $('<input class="ue_date_content ue_date_minute" date_part="minute" idx="' + this.idx + '" />').appendTo(this.frameDom); this.split5 = $('<div class="ue_date_split" idx="' + this.idx + '">:</div>').appendTo(this.frameDom); this.secondDom = $('<input class="ue_date_content ue_date_second" date_part="second" idx="' + this.idx + '" />').appendTo(this.frameDom); this.yearDom.val(this.year); this.monthDom.val(this.toFixStr(this.month + 1)); this.dateDom.val(this.toFixStr(this.date)); this.hourDom.val(this.toFixStr(this.hour)); this.minuteDom.val(this.toFixStr(this.minute)); this.secondDom.val(this.toFixStr(this.second)); this.setSeqByViewType(); var p = this.target.GetRect(); this.frameDom.css({ top: p.top + (this.config.height - 20) / 2, left: p.left }).show(); this.frameDom.children().first().focus().css({ borderColor: '#69c' }); }, initValue: function (s, f) { var v = this.getDateFromText(s, f); this.value = v; this.year = this.calendarYear = v.getFullYear(); this.month = this.calendarMonth = v.getMonth(); this.date = v.getDate(); this.hour = v.getHours(); this.minute = v.getMinutes(); this.second = v.getSeconds(); }, bind: function (tg, f) { if ($('#ue_date_Style').length < 1) { $(this.config.style).appendTo('head'); } var id = UE_CONTROL_IDX++; tg.attr('idx', id).attr('tabindex', id).addClass('ue_date_target').attr('dateFormat', f || this.config.viewType) .off('focus').on('focus', function () { var idx = $(this).attr('idx'); if (idx * 1 != UEDate.idx) { var frm = $('.ue_date_frame[idx=' + UEDate.idx + ']'); if (frm.length > 0) { UEDate.setTargetValue(); frm.remove(); } } UEDate.show(this); }); }, show: function (tg) { var c = this.config; this.target = t = $(tg); this.idx = t.attr('tabindex') * 1; this.viewType = t.attr('dateFormat') || this.config.viewType; c.width = c.width || tg.width(); c.height = c.height || tg.height(); this.initValue(t.val() || t.html(), this.viewType); this.initView(); this.bindEvent(); this.showCalendar(); }, }); $.fn.bindUEDate = function (f) { UEDate.bind($(this), f); }; }()); /* 调用示例 <div id="testDate1" style="160px; height:30px; border:1px solid #ddd; ">25/10/2016 15:24:36</div><br /> <input id="testDate2" style="160px; height:30px; border:1px solid #ddd;" value="18/9/2016 15:24:36" /> <script type="text/javascript"> var dt1 = $('#testDate1').bindUEDate(); var dt2 = $('#testDate2').bindUEDate(); </script> */