(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) {//[function(){...},function(){...}] el = $(this[0]); for (var name in configs) { var value = configs[name]; if (typeof value == 'function') { var obj = {}; obj.click = value; value = obj; //vaule= {click:function(){...}} }; 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 = $('
确定 取消
'); 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 += '
  • '+(lastMonthDays-j)+'
  • '; } //再补上本月的所有天; 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 && option.maxDate<=lastDate){ endDay = maxDateDay; } } //将日期按允许的范围分三段拼接 for(var i=1; i'+i+''; } for(var j=startDay; j<=endDay; j++){ var current = ''; if(y==this.value.year && m==this.value.month && d==j){ current = 'current'; } dayStr += '
  • '+j+'
  • '; } for(var k=endDay+1; k<=currentMonthDays; k++){ dayStr += '
  • '+k+'
  • '; } //再补上下个月的开始几天 var nextMonthStartWeek = (currentMonthDays + week) % 7; if(nextMonthStartWeek!==0){ for(var i=1; i<=7-nextMonthStartWeek; i++){ dayStr += '
  • '+i+'
  • '; } } 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 = $(''); 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(){ var initVal = this.input.val(), 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); } }); }, 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'); } }, '.md_ok' : function(){ 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; } _this.input.val(_this.value.year + '-' + monthValue + '-' + dateValue); _this._hidePanel(); }, '.md_cancel' : function(){ _this._hidePanel(); } }); } } mdater.init(); } })(Zepto);