移动端日历选择控件(支持Zepto和JQuery)

移动端日历选择控件(支持Zepto和JQuery)

 
<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title></title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<script src="js/jquery-3.0.0.min.js"></script>
		<style type="text/css">
			a {
				-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
				-webkit-tap-highlight-color: transparent;
			}
			
			.md_mask {
				 100%;
				height: 100%;
				-moz-transition: opacity .5s linear 0s;
				-webkit-transition: opacity .5s linear 0s;
				-o-transition: opacity .5s linear 0s;
				-ms-transition: opacity .5s linear 0s;
				transition: opacity .5s linear 0s;
				position: absolute;
				top: 0;
				left: 0;
				display: block;
				visibility: hidden;
				background: #000;
				opacity: 0;
				z-index: 1000;
			}
			
			.md_mask.show {
				visibility: visible;
				opacity: 0.25;
			}
			
			.md_panel {
				-moz-transition: -moz-transform .3s ease-in-out 0s;
				-ms-transition: -ms-transform .3s ease-in-out 0s;
				-webkit-transition: -webkit-transform .3s ease-in-out 0s;
				-o-transition: -o-transform .3s ease-in-out 0s;
				transition: transform .3s ease-in-out 0s;
				-ms-transform: translate3d(0, 100%, 0);
				-moz-transform: translate3d(0, 100%, 0);
				-webkit-transform: translate3d(0, 100%, 0);
				-o-transform: translate3d(0, 100%, 0);
				transform: translate3d(0, 100%, 0);
				position: fixed;
				bottom: 0;
				left: 0;
				 100%;
				height: auto;
				z-index: 1100;
				background-color: #F7F7F7;
				font-family: Tahoma, arial, verdana, sans-serif;
				-webkit-user-select: none;
			}
			
			.md_panel.show {
				-ms-transform: translate3d(0, 0, 0);
				-moz-transform: translate3d(0, 0, 0);
				-webkit-transform: translate3d(0, 0, 0);
				-o-transform: translate3d(0, 0, 0);
				transform: translate3d(0, 0, 0);
			}
			
			.md_panel a {
				text-decoration: none;
			}
			
			.md_selectarea {
				display: inline-block;
				 50%;
				position: relative;
			}
			
			.md_head {
				height: 40px;
				line-height: 40px;
			}
			
			.md_body {
				position: relative;
				height: 268px;
			}
			
			.md_headtext {
				display: inline-block;
				 100%;
				text-align: center;
				font-size: 1.125em;
				color: #333;
			}
			
			.md_prev,
			.md_next {
				position: absolute;
				top: 0;
				font-family: arial;
				font-size: 1.6em;
				display: inline-block;
				 40px;
				height: 40px;
				text-align: center;
			}
			
			.md_prev {
				left: 0;
			}
			
			.md_next {
				right: 0;
			}
			
			.md_weekarea {
				margin: 0;
				padding: 0;
				list-style-type: none;
				overflow: hidden;
			}
			
			.md_weekarea li,
			.md_datearea li {
				display: inline-block;
				float: left;
				 14.2857%;
				font-size: .8125em;
				font-weight: 400;
				text-align: center;
				line-height: 3.31em;
			}
			
			.md_weekarea li,
			.md_prev,
			.md_next {
				color: #5b5b5b;
			}
			
			.md_datearea {
				position: absolute;
				 100%;
				list-style-type: none;
				margin: 0;
				padding: 0;
				overflow: hidden;
				-webkit-transition: -webkit-transform .2s ease-in;
				-webkit-transform: translate3d(0, 0, 0);
			}
			
			.md_datearea li.current {
				background-color: #872F9F;
				color: #FFF;
				border-radius: 4px;
			}
			
			.md_datearea li span {
				display: inline-block;
				 100%;
				height: 100%;
			}
			
			.md_datearea li span.current {
				background-color: #872F9F;
				color: #FFF;
			}
			
			.md_foot {
				margin-top: 0.5em;
				margin-bottom: 1em;
				text-align: center;
			}
			
			.md_ok,
			.md_cancel {
				display: -moz-inline-stack;
				display: inline-block;
				*display: inline;
				*zoom: 1;
				 9em;
				height: 2.5em;
				line-height: 2.5em;
				border-radius: 4px;
			}
			
			.md_ok {
				color: #fff;
				background-color: #872F9F;
			}
			
			.md_cancel {
				color: #fff;
				margin-left: 1em;
				background-color: #C6C6C6;
			}
			
			.out_left {
				-webkit-transform: translate3d(-100%, 0, 0);
			}
			
			.out_right {
				-webkit-transform: translate3d(100%, 0, 0);
			}
			
			.prevdate,
			.nextdate {
				color: #999;
			}
			
			.disabled {
				color: #C6C6C6;
			}
		</style>
		<script type="text/javascript">
			(function($) {
				$.fn.mdater = function(config) {
					var defaults = {
						maxDate: null,
						minDate: new Date(1970, 0, 1)
					};
					var option = $.extend(defaults, config);
					//window.console && console.log(this);
					var input = this;

					//通用函数
					var F = {
						//计算某年某月有多少天
						getDaysInMonth: function(year, month) {
							return new Date(year, month + 1, 0).getDate();
						},
						//计算某月1号是星期几
						getWeekInMonth: function(year, month) {
							return new Date(year, month, 1).getDay();
						},
						getMonth: function(m) {
							return ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'][m];
						},
						//计算年某月的最后一天日期
						getLastDayInMonth: function(year, month) {
							return new Date(year, month, this.getDaysInMonth(year, month));
						}
					}

					//为$扩展一个方法,以配置的方式代理事件
					$.fn.delegates = function(configs) {
						el = $(this[0]);
						for(var name in configs) {
							var value = configs[name];
							if(typeof value == 'function') {
								var obj = {};
								obj.click = value;
								value = obj;
							};
							for(var type in value) {
								el.delegate(name, type, value[type]);
							}
						}
						return this;
					}

					var mdater = {
						value: {
							year: '',
							month: '',
							date: ''
						},
						lastCheckedDate: '',
						init: function() {
							this.initListeners();
						},
						renderHTML: function() {
							var $html = $('<div class="md_mask"></div><div class="md_panel"><div class="md_head"><div class="md_selectarea"><a class="md_prev change_year" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_left.png"></a><a class="md_headtext yeartag" href="javascript:void(0);"></a><a class="md_next change_year" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_right.png"></a></div><div class="md_selectarea"><a class="md_prev change_month" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_left.png"></a><a class="md_headtext monthtag" href="javascript:void(0);">月</a> <a class="md_next change_month" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_right.png"></a></div></div><div class="md_body"><ul class="md_weekarea"><li>日</li><li>一</li><li>二</li><li>三</li><li>四</li><li>五</li><li>六</li></ul><ul class="md_datearea in"></ul></div><div class="md_foot"><a href="javascript:void(0);" class="md_ok">确定</a> <a href="javascript:void(0);" class="md_cancel">取消</a></div></div>');
							if($('.md_mask').length == 0) {
								$(document.body).append($html);
							}
							return $html;
						},
						_showPanel: function(container) {
							this.refreshView();
							$('.md_panel, .md_mask').addClass('show');
						},
						_hidePanel: function() {
							//$('.md_panel, .md_mask').removeClass('show');
							$('.md_panel, .md_mask').remove();
						},
						_changeMonth: function(add, checkDate) {

							//先把已选择的日期保存下来
							this.saveCheckedDate();

							var monthTag = $('.md_selectarea').find('.monthtag'),
								num = ~~monthTag.data('month') + add;
							//月份变动发生了跨年
							if(num > 11) {
								num = 0;
								this.value.year++;
								$('.yeartag').text(this.value.year).data('year', this.value.year);
							} else if(num < 0) {
								num = 11;
								this.value.year--;
								$('.yeartag').text(this.value.year).data('year', this.value.year);
							}

							var nextMonth = F.getMonth(num) + '月';
							monthTag.text(nextMonth).data('month', num);
							this.value.month = num;
							if(checkDate) {
								this.value.date = checkDate;
							} else {
								//如果有上次选择的数据,则进行赋值
								this.setCheckedDate();
							}
							this.updateDate(add);
						},
						_changeYear: function(add) {
							//先把已选择的日期保存下来
							this.saveCheckedDate();

							var yearTag = $('.md_selectarea').find('.yeartag'),
								num = ~~yearTag.data('year') + add;
							yearTag.text(num + '年').data('year', num);
							this.value.year = num;

							this.setCheckedDate();

							this.updateDate(add);
						},
						//保存上一次选择的数据
						saveCheckedDate: function() {
							if(this.value.date) {
								this.lastCheckedDate = {
									year: this.value.year,
									month: this.value.month,
									date: this.value.date
								}
							}
						},
						//将上一次保存的数据恢复到界面
						setCheckedDate: function() {
							if(this.lastCheckedDate && this.lastCheckedDate.year == this.value.year && this.lastCheckedDate.month == this.value.month) {
								this.value.date = this.lastCheckedDate.date;
							} else {
								this.value.date = '';
							}
						},
						//根据日期得到渲染天数的显示的HTML字符串
						getDateStr: function(y, m, d) {
							var dayStr = '';
							//计算1号是星期几,并补上上个月的末尾几天
							var week = F.getWeekInMonth(y, m);
							var lastMonthDays = F.getDaysInMonth(y, m - 1);
							for(var j = week - 1; j >= 0; j--) {
								dayStr += '<li class="prevdate" data-day="' + (lastMonthDays - j) + '">' + (lastMonthDays - j) + '</li>';
							}
							//再补上本月的所有天;
							var currentMonthDays = F.getDaysInMonth(y, m);
							//判断是否超出允许的日期范围
							var startDay = 1,
								endDay = currentMonthDays,
								thisDate = new Date(y, m, d),
								firstDate = new Date(y, m, 1);
							lastDate = new Date(y, m, currentMonthDays),
								minDateDay = option.minDate.getDate();

							if(option.minDate > lastDate) {
								startDay = currentMonthDays + 1;
							} else if(option.minDate >= firstDate && option.minDate <= lastDate) {
								startDay = minDateDay;
							}

							if(option.maxDate) {
								var maxDateDay = option.maxDate.getDate();
								if(option.maxDate < firstDate) {
									endDay = startDay - 1;
								} else if(option.maxDate >= firstDate && option.maxDate <= lastDate) {
									endDay = maxDateDay;
								}
							}

							//将日期按允许的范围分三段拼接
							for(var i = 1; i < startDay; i++) {
								dayStr += '<li class="disabled" data-day="' + i + '">' + i + '</li>';
							}
							for(var j = startDay; j <= endDay; j++) {
								var current = '';
								if(y == this.value.year && m == this.value.month && d == j) {
									current = 'current';
								}
								dayStr += '<li class="' + current + '" data-day="' + j + '">' + j + '</li>';
							}
							for(var k = endDay + 1; k <= currentMonthDays; k++) {
								dayStr += '<li class="disabled" data-day="' + k + '">' + k + '</li>';
							}

							//再补上下个月的开始几天
							var nextMonthStartWeek = (currentMonthDays + week) % 7;
							if(nextMonthStartWeek !== 0) {
								for(var i = 1; i <= 7 - nextMonthStartWeek; i++) {
									dayStr += '<li class="nextdate" data-day="' + i + '">' + i + '</li>';
								}
							}

							return dayStr;
						},
						updateDate: function(add) {
							var dateArea = $('.md_datearea.in');
							if(add == 1) {
								var c1 = 'out_left';
								var c2 = 'out_right';
							} else {
								var c1 = 'out_right';
								var c2 = 'out_left';
							}
							var newDateArea = $('<ul class="md_datearea ' + c2 + '"></ul>');
							newDateArea.html(this.getDateStr(this.value.year, this.value.month, this.value.date));
							$('.md_body').append(newDateArea);
							setTimeout(function() {
								newDateArea.removeClass(c2).addClass('in');
								dateArea.removeClass('in').addClass(c1);
							}, 0);

						},
						//每次调出panel前,对界面进行重置
						refreshView: function() {
							if(this.input.hasClass('input-group')) {
								var initVal = this.input.children('input').val();
							} else {
								var initVal = this.input.val();
							}
							var date = null;
							if(initVal) {
								var arr = initVal.split('-');
								date = new Date(arr[0], arr[1] - 1, arr[2]);
							} else {
								date = new Date();
							}
							var y = this.value.year = date.getFullYear(),
								m = this.value.month = date.getMonth(),
								d = this.value.date = date.getDate();
							$('.yeartag').text(y).data('year', y);
							$('.monthtag').text(F.getMonth(m) + '月').data('month', m);
							var dayStr = this.getDateStr(y, m, d);
							$('.md_datearea').html(dayStr);
						},
						input: null, //暂存当前指向input
						initListeners: function() {
							var _this = this;
							input.on('click', function() {
								_this.input = $(this); //暂存当前指向input
								if($('.md_mask').length) {
									_this._hidePanel();
								} else {
									_this.renderHTML();
									var panel = $('.md_panel'),
										mask = $('.md_mask');
									_this.afterShowPanel(mask, panel);
									setTimeout(function() {
										_this._showPanel();
									}, 50);
								}
							});
						},
						saveValueToInput: function() {
							var _this = this;
							var monthValue = ~~_this.value.month + 1;
							if(monthValue < 10) {
								monthValue = '0' + monthValue;
							}
							var dateValue = _this.value.date;
							if(dateValue === '') {
								dateValue = _this.value.date = 1;
							}
							if(dateValue < 10) {
								dateValue = '0' + dateValue;
							}
							if(_this.input.hasClass('input-group')) {
								_this.input.children('input').val(_this.value.year + '-' + monthValue + '-' + dateValue);
								_this.input.children('input').trigger('input');
							} else {
								_this.input.val(_this.value.year + '-' + monthValue + '-' + dateValue);
								_this.input.trigger('input');
							}
							_this._hidePanel();
						},
						afterShowPanel: function(mask, panel) {
							var _this = this;
							mask.on('click', function() {
								_this._hidePanel();
							});
							panel.delegates({
								'.change_month': function() {
									var add = $(this).hasClass('md_next') ? 1 : -1;
									_this._changeMonth(add);
								},
								'.change_year': function() {
									var add = $(this).hasClass('md_next') ? 1 : -1;
									_this._changeYear(add);
								},
								'.out_left, .out_right': {
									'webkitTransitionEnd': function() {
										$(this).remove();
									}
								},
								'.md_datearea li': function() {
									var $this = $(this);
									if($this.hasClass('disabled')) {
										return;
									}
									_this.value.date = $this.data('day');
									//判断是否点击的是前一月或后一月的日期
									var add = 0;
									if($this.hasClass('nextdate')) {
										add = 1;
									} else if($this.hasClass('prevdate')) {
										add = -1;
									}
									if(add !== 0) {
										_this._changeMonth(add, _this.value.date);
									} else {
										$this.addClass('current').siblings('.current').removeClass('current');
										_this.saveValueToInput();
									}
								},
								'.md_cancel': function() {
									_this._hidePanel();
								},
								'.md_ok': function() {
									_this.saveValueToInput();
								}
							});
						}
					}
					mdater.init();
				}
			})(window.Zepto || window.jQuery);
		</script>
		<script type="text/javascript">
			$(function() {
				$('.item-buydate').mdater();
			})
		</script>
	</head>

	<body>
		<div class="item item-buydate input-group">
			<span class="input-group-span no-border-right" id="buydate-span">申购成交时间</span>
			<input class="txt-input txt-buydate no-border-left text-right" type="text" placeholder="请选择申购日期" readonly>
		</div>
	</body>

</html>

  

一. 效果图

二. 功能说明

  1. 支持切换年份,月份。

  2. 支持点击选中日期,也可以点击确定选择日期。

三. 使用方法

  1. 添加Input

    在你的页面中添加Input输入框。可以再html里,也可以JS动态加载。

    我这里使用的时Input-group形式的输入框,是JS加载的。

    一般使用的话,直接写个input输入框就行。

'<div class="item item-buydate input-group">' +
'<span class="input-group-span no-border-right" id="buydate-span">申购成交时间</span>' +
'<input class="txt-input txt-buydate no-border-left text-right" type="text" placeholder="请选择申购日期" readonly>' +
'</div>';

  2. 调用方法

    可选择项目:最大、最小日期。

$('.item-buydate').mdater();

  3. 源代码

    注意:注意更改代码中的图片资源路径。

复制代码
(function($) {
  $.fn.mdater = function(config) {
    var defaults = {
      maxDate: null,
      minDate: new Date(1970, 0, 1)
    };
    var option = $.extend(defaults, config);
    //window.console && console.log(this);
    var input = this;

    //通用函数
    var F = {
      //计算某年某月有多少天
      getDaysInMonth: function(year, month) {
        return new Date(year, month + 1, 0).getDate();
      },
      //计算某月1号是星期几
      getWeekInMonth: function(year, month) {
        return new Date(year, month, 1).getDay();
      },
      getMonth: function(m) {
        return ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'][m];
      },
      //计算年某月的最后一天日期
      getLastDayInMonth: function(year, month) {
        return new Date(year, month, this.getDaysInMonth(year, month));
      }
    }

    //为$扩展一个方法,以配置的方式代理事件
    $.fn.delegates = function(configs) {
      el = $(this[0]);
      for (var name in configs) {
        var value = configs[name];
        if (typeof value == 'function') {
          var obj = {};
          obj.click = value;
          value = obj;
        };
        for (var type in value) {
          el.delegate(name, type, value[type]);
        }
      }
      return this;
    }

    var mdater = {
      value: {
        year: '',
        month: '',
        date: ''
      },
      lastCheckedDate: '',
      init: function() {
        this.initListeners();
      },
      renderHTML: function() {
        var $html = $('<div class="md_mask"></div><div class="md_panel"><div class="md_head"><div class="md_selectarea"><a class="md_prev change_year" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_left.png"></a><a class="md_headtext yeartag" href="javascript:void(0);"></a><a class="md_next change_year" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_right.png"></a></div><div class="md_selectarea"><a class="md_prev change_month" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_left.png"></a><a class="md_headtext monthtag" href="javascript:void(0);">月</a> <a class="md_next change_month" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_right.png"></a></div></div><div class="md_body"><ul class="md_weekarea"><li>日</li><li>一</li><li>二</li><li>三</li><li>四</li><li>五</li><li>六</li></ul><ul class="md_datearea in"></ul></div><div class="md_foot"><a href="javascript:void(0);" class="md_ok">确定</a> <a href="javascript:void(0);" class="md_cancel">取消</a></div></div>');
        if ($('.md_mask').length == 0) { $(document.body).append($html); }
        return $html;
      },
      _showPanel: function(container) {
        this.refreshView();
        $('.md_panel, .md_mask').addClass('show');
      },
      _hidePanel: function() {
        //$('.md_panel, .md_mask').removeClass('show');
        $('.md_panel, .md_mask').remove();
      },
      _changeMonth: function(add, checkDate) {

        //先把已选择的日期保存下来
        this.saveCheckedDate();

        var monthTag = $('.md_selectarea').find('.monthtag'),
          num = ~~monthTag.data('month') + add;
        //月份变动发生了跨年
        if (num > 11) {
          num = 0;
          this.value.year++;
          $('.yeartag').text(this.value.year).data('year', this.value.year);
        } else if (num < 0) {
          num = 11;
          this.value.year--;
          $('.yeartag').text(this.value.year).data('year', this.value.year);
        }

        var nextMonth = F.getMonth(num) + '月';
        monthTag.text(nextMonth).data('month', num);
        this.value.month = num;
        if (checkDate) {
          this.value.date = checkDate;
        } else {
          //如果有上次选择的数据,则进行赋值
          this.setCheckedDate();
        }
        this.updateDate(add);
      },
      _changeYear: function(add) {
        //先把已选择的日期保存下来
        this.saveCheckedDate();

        var yearTag = $('.md_selectarea').find('.yeartag'),
          num = ~~yearTag.data('year') + add;
        yearTag.text(num + '年').data('year', num);
        this.value.year = num;

        this.setCheckedDate();

        this.updateDate(add);
      },
      //保存上一次选择的数据
      saveCheckedDate: function() {
        if (this.value.date) {
          this.lastCheckedDate = {
            year: this.value.year,
            month: this.value.month,
            date: this.value.date
          }
        }
      },
      //将上一次保存的数据恢复到界面
      setCheckedDate: function() {
        if (this.lastCheckedDate && this.lastCheckedDate.year == this.value.year && this.lastCheckedDate.month == this.value.month) {
          this.value.date = this.lastCheckedDate.date;
        } else {
          this.value.date = '';
        }
      },
      //根据日期得到渲染天数的显示的HTML字符串
      getDateStr: function(y, m, d) {
        var dayStr = '';
        //计算1号是星期几,并补上上个月的末尾几天
        var week = F.getWeekInMonth(y, m);
        var lastMonthDays = F.getDaysInMonth(y, m - 1);
        for (var j = week - 1; j >= 0; j--) {
          dayStr += '<li class="prevdate" data-day="' + (lastMonthDays - j) + '">' + (lastMonthDays - j) + '</li>';
        }
        //再补上本月的所有天;
        var currentMonthDays = F.getDaysInMonth(y, m);
        //判断是否超出允许的日期范围
        var startDay = 1,
          endDay = currentMonthDays,
          thisDate = new Date(y, m, d),
          firstDate = new Date(y, m, 1);
        lastDate = new Date(y, m, currentMonthDays),
          minDateDay = option.minDate.getDate();


        if (option.minDate > lastDate) {
          startDay = currentMonthDays + 1;
        } else if (option.minDate >= firstDate && option.minDate <= lastDate) {
          startDay = minDateDay;
        }

        if (option.maxDate) {
          var maxDateDay = option.maxDate.getDate();
          if (option.maxDate < firstDate) {
            endDay = startDay - 1;
          } else if (option.maxDate >= firstDate && option.maxDate <= lastDate) {
            endDay = maxDateDay;
          }
        }


        //将日期按允许的范围分三段拼接
        for (var i = 1; i < startDay; i++) {
          dayStr += '<li class="disabled" data-day="' + i + '">' + i + '</li>';
        }
        for (var j = startDay; j <= endDay; j++) {
          var current = '';
          if (y == this.value.year && m == this.value.month && d == j) {
            current = 'current';
          }
          dayStr += '<li class=" + current + " data-day="' + j + '">' + j + '</li>';
        }
        for (var k = endDay + 1; k <= currentMonthDays; k++) {
          dayStr += '<li class="disabled" data-day="' + k + '">' + k + '</li>';
        }

        //再补上下个月的开始几天
        var nextMonthStartWeek = (currentMonthDays + week) % 7;
        if (nextMonthStartWeek !== 0) {
          for (var i = 1; i <= 7 - nextMonthStartWeek; i++) {
            dayStr += '<li class="nextdate" data-day="' + i + '">' + i + '</li>';
          }
        }

        return dayStr;
      },
      updateDate: function(add) {
        var dateArea = $('.md_datearea.in');
        if (add == 1) {
          var c1 = 'out_left';
          var c2 = 'out_right';
        } else {
          var c1 = 'out_right';
          var c2 = 'out_left';
        }
        var newDateArea = $('<ul class="md_datearea ' + c2 + '"></ul>');
        newDateArea.html(this.getDateStr(this.value.year, this.value.month, this.value.date));
        $('.md_body').append(newDateArea);
        setTimeout(function() {
          newDateArea.removeClass(c2).addClass('in');
          dateArea.removeClass('in').addClass(c1);
        }, 0);

      },
      //每次调出panel前,对界面进行重置
      refreshView: function() {
        if (this.input.hasClass('input-group')) {
          var initVal = this.input.children('input').val();
        } else {
          var initVal = this.input.val();
        }
        var date = null;
        if (initVal) {
          var arr = initVal.split('-');
          date = new Date(arr[0], arr[1] - 1, arr[2]);
        } else {
          date = new Date();
        }
        var y = this.value.year = date.getFullYear(),
          m = this.value.month = date.getMonth(),
          d = this.value.date = date.getDate();
        $('.yeartag').text(y).data('year', y);
        $('.monthtag').text(F.getMonth(m) + '月').data('month', m);
        var dayStr = this.getDateStr(y, m, d);
        $('.md_datearea').html(dayStr);
      },
      input: null, //暂存当前指向input
      initListeners: function() {
        var _this = this;
        input.on('click', function() {
          _this.input = $(this); //暂存当前指向input
          if ($('.md_mask').length) {
            _this._hidePanel();
          } else {
            _this.renderHTML();
            var panel = $('.md_panel'),
              mask = $('.md_mask');
            _this.afterShowPanel(mask, panel);
            setTimeout(function() {
              _this._showPanel();
            }, 50);
          }
        });
      },
      saveValueToInput: function() {
        var _this = this;
        var monthValue = ~~_this.value.month + 1;
        if (monthValue < 10) {
          monthValue = '0' + monthValue;
        }
        var dateValue = _this.value.date;
        if (dateValue === '') {
          dateValue = _this.value.date = 1;
        }
        if (dateValue < 10) {
          dateValue = '0' + dateValue;
        }
        if (_this.input.hasClass('input-group')) {
          _this.input.children('input').val(_this.value.year + '-' + monthValue + '-' + dateValue);
          _this.input.children('input').trigger('input');
        } else {
          _this.input.val(_this.value.year + '-' + monthValue + '-' + dateValue);
          _this.input.trigger('input');
        }
        _this._hidePanel();
      },
      afterShowPanel: function(mask, panel) {
        var _this = this;
        mask.on('click', function() {
          _this._hidePanel();
        });
        panel.delegates({
          '.change_month': function() {
            var add = $(this).hasClass('md_next') ? 1 : -1;
            _this._changeMonth(add);
          },
          '.change_year': function() {
            var add = $(this).hasClass('md_next') ? 1 : -1;
            _this._changeYear(add);
          },
          '.out_left, .out_right': {
            'webkitTransitionEnd': function() {
              $(this).remove();
            }
          },
          '.md_datearea li': function() {
            var $this = $(this);
            if ($this.hasClass('disabled')) {
              return;
            }
            _this.value.date = $this.data('day');
            //判断是否点击的是前一月或后一月的日期
            var add = 0;
            if ($this.hasClass('nextdate')) {
              add = 1;
            } else if ($this.hasClass('prevdate')) {
              add = -1;
            }
            if (add !== 0) {
              _this._changeMonth(add, _this.value.date);
            } else {
              $this.addClass('current').siblings('.current').removeClass('current');
              _this.saveValueToInput();
            }
          },
          '.md_cancel': function() {
            _this._hidePanel();
          },
          '.md_ok': function() {
            _this.saveValueToInput();
          }
        });
      }
    }
    mdater.init();
  }
})(window.Zepto || window.jQuery);
复制代码
复制代码
a {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  -webkit-tap-highlight-color: transparent;
}

.md_mask {
   100%;
  height: 100%;
  -moz-transition: opacity .5s linear 0s;
  -webkit-transition: opacity .5s linear 0s;
  -o-transition: opacity .5s linear 0s;
  -ms-transition: opacity .5s linear 0s;
  transition: opacity .5s linear 0s;
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  visibility: hidden;
  background: #000;
  opacity: 0;
  z-index: 1000;
}

.md_mask.show {
  visibility: visible;
  opacity: 0.25;
}

.md_panel {
  -moz-transition: -moz-transform .3s ease-in-out 0s;
  -ms-transition: -ms-transform .3s ease-in-out 0s;
  -webkit-transition: -webkit-transform .3s ease-in-out 0s;
  -o-transition: -o-transform .3s ease-in-out 0s;
  transition: transform .3s ease-in-out 0s;
  -ms-transform: translate3d(0, 100%, 0);
  -moz-transform: translate3d(0, 100%, 0);
  -webkit-transform: translate3d(0, 100%, 0);
  -o-transform: translate3d(0, 100%, 0);
  transform: translate3d(0, 100%, 0);
  position: fixed;
  bottom: 0;
  left: 0;
   100%;
  height: auto;
  z-index: 1100;
  background-color: #F7F7F7;
  font-family: Tahoma, arial, verdana, sans-serif;
  -webkit-user-select: none;
}

.md_panel.show {
  -ms-transform: translate3d(0, 0, 0);
  -moz-transform: translate3d(0, 0, 0);
  -webkit-transform: translate3d(0, 0, 0);
  -o-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
}

.md_panel a {
  text-decoration: none;
}

.md_selectarea {
  display: inline-block;
   50%;
  position: relative;
}

.md_head {
  height: 40px;
  line-height: 40px;
}

.md_body {
  position: relative;
  height: 268px;
}

.md_headtext {
  display: inline-block;
   100%;
  text-align: center;
  font-size: 1.125em;
  color: #333;
}

.md_prev,
.md_next {
  position: absolute;
  top: 0;
  font-family: arial;
  font-size: 1.6em;
  display: inline-block;
   40px;
  height: 40px;
  text-align: center;
}

.md_prev {
  left: 0;
}

.md_next {
  right: 0;
}

.md_weekarea {
  margin: 0;
  padding: 0;
  list-style-type: none;
  overflow: hidden;
}

.md_weekarea li,
.md_datearea li {
  display: inline-block;
  float: left;
   14.2857%;
  font-size: .8125em;
  font-weight: 400;
  text-align: center;
  line-height: 3.31em;
}

.md_weekarea li,
.md_prev,
.md_next {
  color: #5b5b5b;
}

.md_datearea {
  position: absolute;
   100%;
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
  -webkit-transition: -webkit-transform .2s ease-in;
  -webkit-transform: translate3d(0, 0, 0);
}

.md_datearea li.current {
  background-color: #872F9F;
  color: #FFF;
  border-radius: 4px;
}

.md_datearea li span {
  display: inline-block;
   100%;
  height: 100%;
}

.md_datearea li span.current {
  background-color: #872F9F;
  color: #FFF;
}

.md_foot {
  margin-top: 0.5em;
  margin-bottom: 1em;
  text-align: center;
}

.md_ok,
.md_cancel {
  display: -moz-inline-stack;
  display: inline-block;
  *display: inline;
  *zoom: 1;
   9em;
  height: 2.5em;
  line-height: 2.5em;
  border-radius: 4px;
}

.md_ok {
  color: #fff;
  background-color: #872F9F;
}

.md_cancel {
  color: #fff;
  margin-left: 1em;
  background-color: #C6C6C6;
}

.out_left {
  -webkit-transform: translate3d(-100%, 0, 0);
}

.out_right {
  -webkit-transform: translate3d(100%, 0, 0);
}

.prevdate,
.nextdate {
  color: #999;
}

.disabled {
  color: #C6C6C6;
}

原文地址:https://www.cnblogs.com/libin-1/p/6043015.html