移动端日历选择控件(支持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 {     width: 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;     width: 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;     width: 50%;     position: relative;    }        .md_head {     height: 40px;     line-height: 40px;    }        .md_body {     position: relative;     height: 268px;    }        .md_headtext {     display: inline-block;     width: 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;     width: 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;     width: 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;     width: 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;     width: 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;     width: 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>




一. 效果图

移动端日历选择控件(支持Zepto和JQuery)_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. 源代码

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

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

(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);

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


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

a {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight-color: transparent;
}

.md_mask {
width: 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;
width: 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;
width: 50%;
position: relative;
}

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

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

.md_headtext {
display: inline-block;
width: 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;
width: 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;
width: 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;
width: 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;
width: 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;
width: 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;
}




一. 效果图

移动端日历选择控件(支持Zepto和JQuery)_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. 源代码

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

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

(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);

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


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

a {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight-color: transparent;
}

.md_mask {
width: 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;
width: 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;
width: 50%;
position: relative;
}

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

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

.md_headtext {
display: inline-block;
width: 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;
width: 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;
width: 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;
width: 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;
width: 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;
width: 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;
}