UNPKG

s94-inputdate

Version:

时间选择控件

312 lines (296 loc) 13.9 kB
/** * 时间选择控件 * inputdate(fmt,initdate,callback); * fmt 返回的时间字符串格式样式,YMDHIS分别表示年月日时分秒,大写为有前置0、小写为没有前置0;W为中文的星期几、w为星期序列(0为星期天,1为星期一...)。默认为Y-M-D H:I:S * initdate 初始化时间,字符串,格式和fmt一致,默认为当前时间(new Date()).getTime() * callback 回调函数,传入一个对象,包含属性[y,m,d,h,i,s,strtime] * **如果引入有jQuery,还有jQuery扩展 * $().inputdate(fmt,callback); * 如果操作的DOM对象有value属性(如input标签),那么“初始化时间”对象的value,且选择和会自动修改value属性 */ (function(){ "use strict"; var IDNAME = 's94_inputdate'+(new Date()).getTime(); var FUN_PREFIX = IDNAME+'_'; var now_type='d';//当前选择类型 var has = {d:0,m:0,y:0,t:0}, now = {y:0,m:0,d:0,h:0,i:0,s:0}; //当前时间,包含属性[y,m,d,h,i,s] var doms={}; function init_type(){ for (var k in has) { if(has[k]) return k; } } /** * 插入时间的控件inputdate(callback[, fmt, initdate]) * @param {Object} callback 回调函数 * @param {Object} fmt 【可选】返回的时间字符串格式样式,默认为Y-M-D H:I:S * @param {Object} initdate 【可选】初始化时间,Date|String,为字符串要求格式和fmt一致,默认为当前时间 */ function inputdate(callback, fmt, initdate){ if(!inputdate.container) inputdate.init(); inputdate.fmt = fmt = fmt || 'Y-M-D H:I:S'; has.y = /(^|[^\\])y/i.test(fmt); has.m = /(^|[^\\])m/i.test(fmt); has.d = /(^|[^\\])(d|w)/i.test(fmt); has.t = /(^|[^\\])(h|i|s)/i.test(fmt); if(!has.y&&!has.m&&!has.d&&!has.t) throw new Error('时间字符串格式错误'); if (initdate) { var t = initdate instanceof Date ? initdate : $.strtodate(initdate, fmt); } else { var t = new Date(); t.setMilliseconds(0); if(!has.t) { t.setHours(0); t.setMinutes(0); t.setSeconds(0); } } now.y = t.getFullYear(); now.m = t.getMonth() + 1; now.d = t.getDate(); now.h = t.getHours(); now.i = t.getMinutes(); now.s = t.getSeconds(); now_type = init_type(); inputdate.callback = callback; var rem = $.rem.get(); var vw = document.documentElement.clientWidth, vh = document.documentElement.clientHeight; var mw = 3*rem, mh = 4*rem; if(vw > 7.5*rem && vh > 6*rem && window.event){ var sty={}, exy = $.eventOffsetScreen(); if (exy.x!==undefined && exy.y!==undefined) { sty['position'] = 'absolute'; sty['left'] = (vw-exy.x > mw ? exy.x : exy.x-mw)+'px'; sty['top'] = (vh-exy.y > mh ? exy.y : vh-mh)+'px'; }; $(doms.body).css(sty); }else{ $(doms.body).attr('style',''); } $(inputdate.container).css('font-size',rem+'px').show(); display(); } inputdate.init = function(config){ var SETUP = { color: '#307cc4', week: ['日','一','二','三','四','五','六'], month: ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], img_left2: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAS1BMVEVMaXH///////////////////////////////////////////////////////////////////////////////////////////////9UrLx+AAAAGHRSTlMAIfUd6vsyJPkXJvQtEin3Ou/nbUimeQWjo8UCAAAAt0lEQVR42r3Qyw6EIAwFUORZAUXUce7/f+kMj8QFdTnTzU160oYi/lnr8e65MLpoHDV3XKPOGbBNcQ6q9K12nNUwsSWv9Kwqw9iuG6eougORfXOsl7Gq2c239s2cbgCpbzoDODHUCYTyxRZIsxhrkkiujBNo5TwgVE+QD06+ZEZyjHsCTW0+KcZX6vsJ6WF/dm2P9Iy7gKD6POc+tL4LzPv63aU/JZht0No/SiqJSzB1vlTPKH5dH/87DEZvAY7FAAAAAElFTkSuQmCC', img_left: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAS1BMVEVMaXH///////////////////////////////////////////////////////////////////////////////////////////////9UrLx+AAAAGHRSTlMANcejjJVVRpo+pe1LIPZbd4G66S+2rSmsbrQsAAAAXElEQVR42s3MWQ5AQBRE0Uej2zxz979SK3glkRD396TKvm7MlFbkUpl8jTD7WkPxVDMofd0g+XoOBF/7gUNoy25+LbmJStaovIBO7u9d/qf3vVYe0N6Ayf1if+gCodcFK+0LnW4AAAAASUVORK5CYII=', }; config = $.merge(SETUP, config); var html = '<style type="text/css">'; html += '#'+IDNAME+'{display: flex;justify-content: center;align-items: center;position: fixed;left: 0;top: 0;width: 100%;height: 100%;color: #333;z-index: 999999999;}\n'; html += '#'+IDNAME+' *{box-sizing: border-box;margin: 0;padding: 0;-webkit-tap-highlight-color: rgba(0,0,0,0);}\n'; html += '#'+IDNAME+' li{list-style: none;}\n'; html += '#'+IDNAME+' span{font-size: 0.2em;line-height: 1.5;user-select: none;display: flex;justify-content: center;align-items: center;width: 100%;height: 100%;cursor: pointer;}\n'; html += '#'+IDNAME+'>p{position: absolute;left: 0;top: 0;width: 100%;height: 100%;z-index: 0;}\n'; html += '#'+IDNAME+'>div{background: #fff;width: 3em;font-size: 1em;position: relative;z-index: 2;box-shadow: 0 0 0.04em 0 '+config.color+';}\n'; html += '#'+IDNAME+'>div>header{display: flex;border-bottom: 1px solid #e2e2e2;height: 0.6em;margin-bottom: 0.1em;background: '+config.color+';color: #fff;justify-content: space-between;align-items: center;}\n'; html += '#'+IDNAME+'>div>header>*{display: block;width: 0.3em;height: 0.3em;margin:0 0.05em;cursor: pointer;background-size: 100%;}\n'; html += '#'+IDNAME+'>div>header>b{background-image: url('+config.img_left2+');}\n'; html += '#'+IDNAME+'>div>header>i{background-image: url('+config.img_left+');}\n'; html += '#'+IDNAME+'>div>header>b[back],#'+IDNAME+'>div>header>i[back]{transform: rotate(180deg);}\n'; html += '#'+IDNAME+'>div>header>div{color: #fff;flex-grow: 2;}\n'; html += '#'+IDNAME+'>div>ul{display: flex;flex-wrap: wrap;justify-content: space-around;overflow: hidden;padding: 0 0.05em;}\n'; html += '#'+IDNAME+'>div>ul>*{width: 0.9em;height: 0.37em;}'; html += '#'+IDNAME+'>div>ul li:hover{background-color: #eaeaea;}\n'; html += '#'+IDNAME+'>div>ul li.on{background-color: '+config.color+';color: #fff;}\n'; html += '#'+IDNAME+'>div>ul[type="day"]>li{width: 0.4em;}\n'; html += '#'+IDNAME+'>div>ul[type="month"]>li{margin: 0.14em 0;}\n'; html += '#'+IDNAME+'>div>ul[type="year"]>li{margin: 0.07em 0;}\n'; html += '#'+IDNAME+'>div>ul>ol{position: relative;border: 1px solid #e2e2e2;height: 2.2em;cursor: default;overflow-y: scroll;}\n'; html += '#'+IDNAME+'>div>ul>ol::-webkit-scrollbar {display: none;}'; html += '#'+IDNAME+'>div>ul>ol>li{width: 100%;height: 0.0.37em;margin: 0.06em 0;}'; html += '#'+IDNAME+'>div>footer{background: #fff;display: flex;border-top: 1px solid #e2e2e2;height: 0.6em;margin-top: 0.1em;padding: 0 0.1em;justify-content: space-between;align-items: center;}\n'; html += '#'+IDNAME+'>div>footer>*{display: flex;}\n'; html += '#'+IDNAME+'>div>footer>ol>li{border: 1px solid #C9C9C9;border-radius: 0.04em;margin: 0 0.01em;padding: 0 0.05em;}\n'; html += '#'+IDNAME+'>div[type="y"]>header>i,#'+IDNAME+'>div[type="m"]>header>i,#'+IDNAME+'>div[type="t"]>header>b,#'+IDNAME+'>div[type="t"]>header>i{display: none;}\n'; html += '</style><p onclick="$(this).parent().hide()"></p><div type="day">'; html += '<header><b onclick="'+FUN_PREFIX+'change_year()"></b><i onclick="'+FUN_PREFIX+'change_month()"></i><div></div><i onclick="'+FUN_PREFIX+'change_month(1)" back></i><b onclick="'+FUN_PREFIX+'change_year(1)" back></b></header>'; html+='<ul type="year" style="display: none;">'; for (var i=0;i<15;i++) { html+='<li data=""><span></span></li>'; } html+='</ul><ul type="month" style="display: none;">'; for (i=0;i<12;i++) { html+='<li data="'+(i+1)+'"><span>'+config.month[i]+'</span></li>'; } html += '</ul><ul type="day" style="display: none;">'; for (var i=0;i<7;i++) { html+='<li><span>'+config.week[i]+'</span></li>'; } for (var i=0;i<31;i++) { html+='<li data="'+(i+1)+'"><span>'+(i+1)+'</span></li>'; } html+='</ul><ul type="time" style="display: none;"><p><span>时</span></p><p><span>分</span></p><p><span>秒</span></p><ol type="h">'; for (i=0;i<24;i++) { html+='<li data="'+i+'"><span>'+(i<10?'0'+i:i)+'</span></li>'; } html+='</ol><ol type="i">'; for (i=0;i<60;i++) { html+='<li data="'+i+'"><span>'+(i<10?'0'+i:i)+'</span></li>'; } html+='</ol><ol type="s">'; for (i=0;i<60;i++) { html+='<li data="'+i+'"><span>'+(i<10?'0'+i:i)+'</span></li>'; } html+='</ol></ul><footer><p></p><ol><li onclick="'+FUN_PREFIX+'clear()"><span>清空</span></li><li onclick="'+FUN_PREFIX+'now()"><span>现在</span></li><li onclick="'+FUN_PREFIX+'ok()"><span>确定</span></li></ol></footer></div>'; if(!inputdate.container){ inputdate.container = document.createElement('div'); inputdate.container.id = IDNAME; document.documentElement.appendChild(inputdate.container); } inputdate.container.style.display = 'none'; inputdate.container.innerHTML = html; doms.body = document.querySelector('#'+IDNAME+'>div'); doms.title = doms.body.querySelector('header>div'); doms.footer = doms.body.querySelector('footer>p'); doms.y = doms.body.querySelector('ul[type="year"]'); doms.m = doms.body.querySelector('ul[type="month"]'); doms.d = doms.body.querySelector('ul[type="day"]'); doms.t = doms.body.querySelector('ul[type="time"]'); $('#'+IDNAME+' li[data]').on('click',function(){ $(this).parent().find('li').removeClass('on'); var v = $(this).addClass('on').attr('data')*1; if(now_type=='t'){ now[$(this).parent().attr('type')] = v; }else{ now[now_type] = v; var ks = ['y','m','d','t']; for (var i = ks.indexOf(now_type)+1; i < 4; i++) { if(has[ks[i]]) return display(ks[i]); } close(); } }) //全局方法 window[FUN_PREFIX+'change_year'] = function(add){ if (add) { now.y += (now_type=='y' ? 15 : 1); } else{ now.y -= (now_type=='y' ? 15 : 1); } display(now_type); } window[FUN_PREFIX+'change_month'] = function(add){ add ? (now.m++) : (now.m--); if(now.m > 12){ now.y++;now.m=1; } if(now.m < 1){ now.y--;now.m=12; } display(now_type); } window[FUN_PREFIX+'display'] = display; window[FUN_PREFIX+'clear'] = function(){ close(false); } window[FUN_PREFIX+'now'] = function(){ var t = new Date(); now={ y: t.getFullYear(), m: t.getMonth() + 1, d: t.getDate(), h: t.getHours(), i: t.getMinutes(), s: t.getSeconds(), } display(now_type); } window[FUN_PREFIX+'ok'] = function(){ close(); } } /*计算指定月份多少天*/ function day_num_month(y,m){ var isRun = !((y%100) ? (y%4) : (y%400)); return m==2?(isRun?29:28):(m==4||m==6||m==9||m==11?30:31) } function display(type){ now_type = type || init_type(); $(doms.body).attr('type',now_type); $('#'+IDNAME+'>div>ul').hide(); $(doms[now_type]).show().find('li.on').removeClass('on'); display[now_type](); if(now_type=='t'){ $(doms.footer).html((has.d||has.y||has.m) ? '<span onclick="'+FUN_PREFIX+'display()">选择日期</span>' : ''); }else{ $(doms.footer).html(has.t ? '<span onclick="'+FUN_PREFIX+'display(\'t\')">'+now.h+' : '+now.i+' : '+now.s+'</span>':''); } } display.y = function(){ var num = 15; var start = now.y - (now.y)%num; $(doms.title).html('<span>'+start+'年~'+(start+num-1)+'年</span>'); $(doms.y).find('li').each(function(){ if(start==now.y) $(this).addClass('on'); $(this).attr('data', start).html('<span>'+start+'年</span>');start++; }) } display.m = function(){ $(doms.title).html('<span onclick="'+FUN_PREFIX+'display(\'y\')">'+now.y+'年</span>'); $(doms.m).find('li').eq(now.m-1).addClass('on'); } display.d = function(){ $(doms.title).html('<span><font onclick="'+FUN_PREFIX+'display(\'y\')">'+now.y+'年</font> <font onclick="'+FUN_PREFIX+'display(\'m\')">'+now.m+'月</font></span>'); //渲染选择日期 $(doms.d).find('li[empty]').remove(); var html = '',i; var day_num = day_num_month(now.y, now.m);//当前月有多少天 var first_day_w = (new Date(now.y+'/'+now.m+'/1')).getDay(); //当前月的第一天是星期几 var $days = $(doms.d).find('li'); for(i=27; i<31; i++) { i<day_num ? $days.eq(i+7).show() : $days.eq(i+7).hide(); } $days.eq(now.d+6).addClass('on'); for(i=0,html=''; i<first_day_w; i++){ html += '<li empty></li>'; } $days.eq(6).after(html); for(i+=day_num,html=''; i<42; i++){ html += '<li empty></li>'; } $(doms.d).append(html); } display.t = function(){ $(doms.title).html('<span>选择时间</span>'); var ks = ['h','i','s']; $(doms.t).find('ol').each(function(dom, i){ var on = this.querySelectorAll('li')[now[ks[i]]]; $(on).addClass('on'); this.scrollTop = on.offsetTop-(this.offsetHeight/2); }) } display.i = function(){ $(doms.title).html('<span>分</span>'); $(doms.i).find('li').eq(now.i).addClass('on'); } display.s = function(){ $(doms.title).html('<span>秒</span>'); $(doms.s).find('li').eq(now.s).addClass('on'); } function close(ac){ var res={ value: '', valueOf: function(){return this.value}, toString: function(){return this.value}, y:0,m:0,d:0,h:0,i:0,s:0,w:0, Date:null, }; $('.datetime-outer').hide(); if (ac!==false) { for (var k in now) { res[k] = now[k]; } res.Date = new Date(res.y, res.m-1, res.d, res.h, res.i, res.s), res.w = res.Date.getDay(); res.value = $.date(inputdate.fmt, res.Date); } typeof(inputdate.callback)=="function" && inputdate.callback(res); $('#'+IDNAME).hide(); } module.exports = inputdate; })(require('s94-web'));