无依赖的javascript日期选择控件

180it 2020-06-01 PM 104℃ 0条

抽时间自己写了个不依赖第三方js的日期控件,小清新风格,使用简单,操作也很简单。

第一步,引入js:

<script src="date-util.js">< /script>
<!--渲染有问题,只好多加了个空格-->
第二步,绑定输入框:

<script>
DateUtil.bind(document.getElementById('id'));
< /script>
<!--渲染有问题,只好多加了个空格-->
功能:

输入框获得焦点时显示日期控件。鼠标点击其他部位消失。
鼠标放到月份和年份上时,会显示向左和向右的按钮,点击分别加减年份和月份。
支持中英文切换。
支持改变日期控件大小(宽度)。
支持自定义css样式。
通过DateUtil.config({});进行一些简单的设置,如:

//设置大小
DateUtil.config({width:400});

//中英文切换
DateUtil.config({lang:'zh'});
DateUtil.config({lang:'en'});

//自定义css样式
DateUtil.config({style:'.date-util-layer{position:absolute;......}'});

完整代码:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>日期控件</title>
      <script src="date-util.js"></script>
    </head>
    <body>
      <input id="day" type="text">
      <p></p>
      <button onclick="DateUtil.config({lang:'en'});">英文</button>
      <button onclick="DateUtil.config({lang:'zh'});">中文</button>
      <button onclick="DateUtil.config({width:400});">变大</button>
      <button onclick="DateUtil.config({width:200});">变小</button>
      <script>
        DateUtil.bind(document.getElementById('day'));
      </script>
    </body>
    </html>


date-util.js 代码
;(function(W,D){
  var DomUtil = (function(){
    var EV =function(el,e,func){
      func.call(el,W.event||e);
      if(e.stopPropagation){
        e.stopPropagation();
      }else{
        e.cancelBubble = true;
      }
      if(e.preventDefault){
        e.preventDefault();
      }else{
        e.returnValue = false;
      }
    };
    var E=[
      function(el,v,func){
        el.attachEvent('on' + v,function(e){EV(el,e,func);});
      },
      function(el,v,func){
        el.addEventListener(v,function(e){EV(el,e,func);},false);
      }
    ];
    var S=[
      function(s){
        D.createStyleSheet().cssText = s;
      },
      function(s){
        var o=D.createElement('style');
        o.type='text/css';
        o.innerHTML=s;
        D.getElementsByTagName('head')[0].appendChild(o);
      }
    ];
    var C=[
      function(el,css){el.style.cssText = css;},
      function(el,css){el.setAttribute('style',css);}
    ];
    var Z=[
      function(o,s){o.className=s;},
      function(o,s){o.setAttribute('class',s);}
    ];
    var _try = function(funcs,args){
      for(var i=0,j=funcs.length;i<j;i++){
        var func = funcs[i];
        try{
          func.apply(func,args);
          break;
        }catch(e){}
      }
    };
    var _addEvent = function(el,v,func){
      _try(E,[el,v,func]);
    };
    var _setStyle = function(el,css){
      _try(C,[el,css]);
    };
    var _addStyle = function(el,css){
      _setStyle(el,el.style.cssText+';'+css);
    };
    var _style = function(css){
      _try(S,[css]);
    };
    var _setClass = function(el,className){
      _try(Z,[el,className]);
    };
    var _getLocation = function(o){
      var x=0,y=0;
      switch(o.length){
      case 1:
        var r=_getLocation([]);
        var m=o[0];
        if(m.getBoundingClientRect){
          x=m.getBoundingClientRect().left + r.x - D.documentElement.clientLeft;
          y=m.getBoundingClientRect().top + r.y - D.documentElement.clientTop;
        }else{
          for(;m;x+=m.offsetLeft,y+=m.offsetTop,m=m.offsetParent);
        }
        break;
      default:
        x=Math.max(D.documentElement.scrollLeft,D.body.scrollLeft);
        y=Math.max(D.documentElement.scrollTop,D.body.scrollTop);
      }
      return {x:x,y:y};
    };
    var _getSize=function(o){
      var w=0,h=0;
      switch(o.length){
      case 1:
        var m=o[0];
        w=m.offsetWidth;
        h=m.offsetHeight;
        break;
      default:
        w=D.documentElement.clientWidth;
        h=D.documentElement.clientHeight;
      }
      return {width:w,height:h};
    };
    return {
      addEvent:function(el,v,func){_addEvent(el,v,func);},
      setStyle:function(el,css){_setStyle(el,css);},
      addStyle:function(el,css){_addStyle(el,css);},
      style:function(css){_style(css);},
      setClass:function(el,className){_setClass(el,className);},
      getLocation:function(){return _getLocation(arguments);},
      getSize:function(){return _getSize(arguments);}
    };
  })();
  var SolarUtil = (function(){
    var _isLeapYear = function(year){
      var leap = false;
      if(year%4==0) leap = true;
      if(year%100==0) leap = false;
      if(year%400==0) leap = true;
      return leap;
    };
    return {
      DAYS_OF_MONTH:[31,28,31,30,31,30,31,31,30,31,30,31],
      isLeapYear:function(y){return _isLeapYear(y);},
      getDaysOfMonth:function(year,month){
        var m = month-1;
        var d = this.DAYS_OF_MONTH[m];
        if(m==1&&this.isLeapYear(year)){
          d++;
        }
        return d;
      }
    };
  })();
  var SolarMonth = (function(){
    var _fromDate = function(date){
      return _fromYm(date.getFullYear(),date.getMonth()+1);
    };
    var _fromYm = function(y,m){
      var solarMonth = {
        _p:{
          year:y,
          month:m,
          calendar:new Date(y+'/'+m+'/1')
        },
        getYear:function(){
          return this._p.year;
        },
        getMonth:function(){
          return this._p.month;
        },
        next:function(months){
          var date = new Date(this._p.year+'/'+this._p.month+'/1');
          date.setMonth(date.getMonth()+months);
          return _fromDate(date);
        },
        getDays:function(){
          var l = [];
          var d = Solar.fromYmd(this._p.year,this._p.month,1);
          l.push(d);
          var days = SolarUtil.getDaysOfMonth(this._p.year,this._p.month);
          for(var i = 1;i<days;i++){
            l.push(d.next(i));
          }
          return l;
        }
      };
      return solarMonth;
    };
    return {
      fromYm:function(y,m){return _fromYm(y,m);},
      fromDate:function(date){return _fromDate(date);}
    };
  })();
  var Solar = (function(){
    var _fromDate = function(date){
      return _fromYmd(date.getFullYear(),date.getMonth()+1,date.getDate());
    };
    var _fromYmd = function(y,m,d){
      var solar = {
        _p:{
          year:y,
          month:m,
          day:d,
          calendar:new Date(y+'/'+m+'/'+d)
        },
        getYear:function(){
          return this._p.year;
        },
        getMonth:function(){
          return this._p.month;
        },
        getDay:function(){
          return this._p.day;
        },
        getWeek:function(){
          return this._p.calendar.getDay();
        },
        isLeapYear:function(){
          return SolarUtil.isLeapYear(this._p.year);
        },
        toString:function(){
          return [this._p.year,(this._p.month<10?'0':'')+this._p.month,(this._p.day<10?'0':'')+this._p.day].join('-');
        },
        next:function(days){
          var date = new Date(this._p.year+'/'+this._p.month+'/'+this._p.day);
          date.setDate(date.getDate()+days);
          return _fromDate(date);
        }
      };
      return solar;
    };
    return {
      fromYmd:function(y,m,d){return _fromYmd(y,m,d);},
      fromDate:function(date){return _fromDate(date);}
    };
  })();
  var DateUtil = (function(){
    var DOM = {
      layer:null,
      mask:null,
      yearLeft:null,
      yearInfo:null,
      yearRight:null,
      monthLeft:null,
      monthInfo:null,
      monthRight:null,
      weeks:[],
      days:[],
      input:null
    };
    var LANG = {
      zh:{
        week:'日,一,二,三,四,五,六',
        month:'一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月'
      },
      en:{
        week:'SUN,MON,TUE,WED,THU,FRI,SAT',
        month:'January,February,March,April,May,June,July,August,September,October,November,December'
      }
    };
    var MONTH = null;
    var CFG = {
      width:240,
      lang:'zh',
      style:'.date-util-mask{-webkit-user-select:none;display:none;position:absolute;left:0;top:0;width:100%;height:100%;background:#FFF;z-index:999;-webkit-opacity:.1;-moz-opacity:.1;opacity:.1;-khtml-opacity:.1;filter:alpha(opacity=10);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=10)";filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=10)";}'
           +'.date-util-layer{-webkit-user-select:none;display:none;position:absolute;left:0;top:0;background:#FFF;z-index:1000;-webkit-box-shadow:0 2px 5px 0 rgba(0, 0, 0, 0.16),0 2px 10px 0 rgba(0, 0, 0, 0.12);-moz-box-shadow:0 2px 5px 0 rgba(0, 0, 0, 0.16),0 2px 10px 0 rgba(0, 0, 0, 0.12);-ms-box-shadow:0 2px 5px 0 rgba(0, 0, 0, 0.16),0 2px 10px 0 rgba(0, 0, 0, 0.12);-o-box-shadow:0 2px 5px 0 rgba(0, 0, 0, 0.16),0 2px 10px 0 rgba(0, 0, 0, 0.12);box-shadow:0 2px 5px 0 rgba(0, 0, 0, 0.16),0 2px 10px 0 rgba(0, 0, 0, 0.12);}'
           +'.date-util-layer *{-webkit-user-select:none;font-family:sans-serif;cursor:default}'
           +'.date-util-bar{position:relative;background:#03a9f4;width:100%;height:40px;}'
           +'.date-util-bar-arrow{display:none;position:absolute;top:0;width:40px;height:40px;text-align:center;color:#FFF;line-height:30px;font-size:20px;cursor:pointer;}'
           +'.date-util-bar-left{left:0;z-index:1}'
           +'.date-util-bar-right{right:0;z-index:1}'
           +'.date-util-bar-info{color:#FFF;text-align:center;z-index:-1;line-height:40px;overflow:hidden;}'
           +'.date-util-year{font-size:18px;-webkit-opacity:.7;-moz-opacity:.7;opacity:.7;-khtml-opacity:.7;filter:alpha(opacity=70);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";}'
           +'.date-util-month{font-size:26px;line-height:30px}'
           +'.date-util-layer b{display:block;float:left;width:14.28571%;height:20px;line-height:25px;text-align:center;overflow:hidden;font-size:12px;font-weight:normal;color:#A7A7A7;}'
           +'.date-util-layer a{position:relative;display:block;float:left;width:14.28571%;text-align:center;overflow:hidden;text-decoration:none;cursor:pointer;font-size:12px;color:#333;-webkit-border-radius:50%;-moz-border-radius:50%;-ms-border-radius:50%;-o-border-radius:50%;border-radius:50%;-webkit-transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;-moz-transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;-ms-transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;-o-transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;}'
           +'.date-util-layer a i{position:absolute;left:5%;top:5%;z-index:-1;display:block;-webkit-transform:scale(0);-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);width:90%;height:90%;-webkit-border-radius:50%;-moz-border-radius:50%;-ms-border-radius:50%;-o-border-radius:50%;border-radius:50%;-webkit-transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;-moz-transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;-ms-transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;-o-transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;}'
           +'.date-util-layer a.today,.date-util-layer a:hover{color:#FFF}'
           +'.date-util-layer a.today i,.date-util-layer a:hover i{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1);background-color:#03a9f4;}'
           +'.date-util-layer a.none{display:none}'
    };
    var _config = function(cfg){
      if(!cfg) return;
      for(var i in cfg){
        var ov = CFG[i];
        var nv = cfg[i];
        CFG[i] = nv;
        if(nv!=ov){
          _trigger(i);
        }
      }
    };
    var _trigger = function(key){
      if(!DOM.layer) return;
      var v = CFG[key];
      switch(key){
        case 'width':
          DOM.layer.style.width = v+'px';
          var h = Math.floor(v*0.1428571);
          DomUtil.style('.date-util-layer a{height:'+h+'px;line-height:'+h+'px}');
        break;
        case 'lang':
          var ws = LANG[v].week.split(',');
          for(var i=0;i<7;i++){
            DOM.weeks[i].innerHTML = ws[i];
          }
        break;
      }
    };
    var _repaint = function(){
      if(!MONTH){
        MONTH = SolarMonth.fromDate(new Date());
      }
      var today = Solar.fromDate(new Date()).toString();
      var y = MONTH.getYear();
      var m = MONTH.getMonth();
      var days = SolarUtil.getDaysOfMonth(y,m);
      var firstDay = Solar.fromYmd(y,m,1);
      var firstDayWeek = firstDay.getWeek();
      for(var i=0;i<37;i++){
        var a = DOM.days[i];
        DomUtil.setClass(a,'');
        if(i<firstDayWeek){
          a.innerHTML = '';
          a.onclick = function(){return false;};
        }else if(i>=days+firstDayWeek){
          DomUtil.setClass(a,'none');
        }else{
          var d = i+1-firstDayWeek;
          a.innerHTML = '<i></i>'+d;
          var day = [y,(m<10?'0':'')+m,(d<10?'0':'')+d].join('-');
          a.setAttribute('data-ymd',day);
          if(day==today){
            DomUtil.setClass(a,'today');
          }
          a.onclick = function(){
            DOM.input.value = this.getAttribute('data-ymd');
            _hide();
          };
        }
      }
      DOM.yearInfo.innerHTML = MONTH.getYear();
      var ms = LANG[CFG['lang']].month.split(',');
      DOM.monthInfo.innerHTML = ms[MONTH.getMonth()-1];
    };
    var _nextMonth = function(n){
      MONTH = MONTH.next(n);
      _repaint();
    };
    var _init = function(){
      if(DOM.layer) return;
      DomUtil.style(CFG.style);
      var mask = D.createElement('div');
      DomUtil.setClass(mask,'date-util-mask');
      D.body.appendChild(mask);
      DOM.mask = mask;
      var layer = D.createElement('div');
      DomUtil.setClass(layer,'date-util-layer');
      
      var yearLayer = D.createElement('div');
      DomUtil.setClass(yearLayer,'date-util-bar');
      
      var yearLeft = D.createElement('div');
      DomUtil.setClass(yearLeft,'date-util-bar-arrow date-util-bar-left');
      yearLeft.innerHTML = '&#8249;';
      yearLayer.appendChild(yearLeft);
      DOM.yearLeft = yearLeft;
      
      var yearInfo = D.createElement('div');
      DomUtil.setClass(yearInfo,'date-util-bar-info date-util-year');
      yearLayer.appendChild(yearInfo);
      DOM.yearInfo = yearInfo;

      var yearRight = D.createElement('div');
      DomUtil.setClass(yearRight,'date-util-bar-arrow date-util-bar-right');
      yearRight.innerHTML = '&#8250;';
      yearLayer.appendChild(yearRight);
      DOM.yearRight = yearRight;
      
      layer.appendChild(yearLayer);
      
      var monthLayer = D.createElement('div');
      DomUtil.setClass(monthLayer,'date-util-bar');
      var monthLeft = D.createElement('div');
      DomUtil.setClass(monthLeft,'date-util-bar-arrow date-util-bar-left');
      monthLeft.innerHTML = '&#8249;';
      monthLayer.appendChild(monthLeft);
      DOM.monthLeft = monthLeft;
      
      var monthInfo = D.createElement('div');
      DomUtil.setClass(monthInfo,'date-util-bar-info date-util-month');
      monthLayer.appendChild(monthInfo);
      DOM.monthInfo = monthInfo;
      
      var monthRight = D.createElement('div');
      DomUtil.setClass(monthRight,'date-util-bar-arrow date-util-bar-right');
      monthLayer.appendChild(monthRight);
      monthRight.innerHTML = '&#8250;';
      DOM.monthRight = monthRight;
      
      layer.appendChild(monthLayer);
      DomUtil.addEvent(monthLayer,'mouseover',function(e){
        DOM.monthLeft.style.display = 'block';
        DOM.monthRight.style.display = 'block';
      });
      DomUtil.addEvent(monthLayer,'mouseout',function(e){
        DOM.monthLeft.style.display = 'none';
        DOM.monthRight.style.display = 'none';
      });
      DomUtil.addEvent(yearLayer,'mouseover',function(e){
        DOM.yearLeft.style.display = 'block';
        DOM.yearRight.style.display = 'block';
      });
      DomUtil.addEvent(yearLayer,'mouseout',function(e){
        DOM.yearLeft.style.display = 'none';
        DOM.yearRight.style.display = 'none';
      });
      DomUtil.addEvent(DOM.monthLeft,'click',function(e){
        _nextMonth(-1);
      });
      DomUtil.addEvent(DOM.monthRight,'click',function(e){
        _nextMonth(1);
      });
      DomUtil.addEvent(DOM.yearLeft,'click',function(e){
        _nextMonth(-12);
      });
      DomUtil.addEvent(DOM.yearRight,'click',function(e){
        _nextMonth(12);
      });
      for(var i=0;i<7;i++){
        var b = D.createElement('b');
        layer.appendChild(b);
        DOM.weeks.push(b);
      }
      for(var i=0;i<37;i++){
        var a = D.createElement('a');
        layer.appendChild(a);
        DOM.days.push(a);
      }
      D.body.appendChild(layer);
      DOM.layer = layer;
      DomUtil.addEvent(DOM.mask,'mousedown',function(e){
        _hide();
      });
      _trigger('width');
      _trigger('lang');
    };
    var _show = function(){
      DOM.mask.style.display = 'block';
      var loc = DomUtil.getLocation(DOM.input);
      var size = DomUtil.getSize(DOM.input);
      DomUtil.addStyle(DOM.layer,'display:block;left:'+loc.x+'px;top:'+(loc.y+size.height+5)+'px;');
      _repaint();
    };
    var _hide = function(){
      DOM.layer.style.display = 'none';
      DOM.mask.style.display = 'none';
      try{
        DOM.input.blur();
      }catch(e){}
      DOM.input = null;
      MONTH = null;
    };
    var _bind = function(el){
      _init();
      DomUtil.addEvent(el,'focus',function(e){
        DOM.input = this;
        _show();
      });
    };
    return {
      config:function(cfg){_config(cfg);},
      bind:function(el){_bind(el);}
    };
  })();
  W.DateUtil = DateUtil;
})(window,document);

效果图:
593abc729069dfe55d377ab1.jpg

来源:http://6tail.cn/demos/calendar/calendar.html

支付宝打赏支付宝打赏 微信打赏微信打赏

如果文章或资源对您有帮助,欢迎打赏作者。一路走来,感谢有您!

标签: none

无依赖的javascript日期选择控件