<!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>
一. 效果图
二. 功能说明
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 {
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;
}
一. 效果图
二. 功能说明
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 {
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;
}