日历实现
Posted 心素如简,人淡如菊。
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日历实现相关的知识,希望对你有一定的参考价值。
日历要实现下面两种效果,图一是周数据,左右滑动切换不同周的数据。下拉后,切换成月数据即图二。在月数据视图下,上滑切换成周数据。
/** * 日历插件 依赖zepto.js * 使用: * Calendar.initialize(\'.calendar-zone\'); Calendar.fBind("dateChange", function(date) { //日历上选中的日期 self.selectedDate = date; }); */ define(function(require,exports,module){ var Swipe = require(\'./swipe\'); var Calendar = { /** * 初始化日历数据 * @param {[type]} selector 日历数据填充到哪个元素 * @param {[type]} type week month 生成周日历 or 月日历 */ _config:{ MONTH:"month", //生成一周数据还是一月数据 WEEK:"week", SlideTime:400 //动画效果的时间 }, initialize: function(selector){ this.type = this._config.WEEK; this.selector = selector; var title_calendar = this.fGetCalendarTitle(); $(selector).html(title_calendar); this.initProp(); this.fRender(this.CurYear,this.CurMonth,this.CurDay); }, initProp: function(){ var d = new Date(); this.CurYear = d.getFullYear(); this.CurMonth = d.getMonth(); this.CurDay = d.getDate(); this.MonthData = this.fGetCalendarData_month(this.CurYear,this.CurMonth); this.WeekIndex = this.fCalculatePos(this.MonthData,this.CurYear,this.CurMonth,this.CurDay); this.MaxWeek = this.MonthData.length / 7; this.eventDate = []; //有事件的日期 this.callback = {}; // {dateChange:callback} var m = this.CurMonth +1; this.selectedDate = this.CurYear+"-"+m+"-"+this.CurDay; //日历上选中的日期 this._width = $(".calendar-content-pas").width(); //日历控件宽度 this._initTop = -$(".calendar-title-pas").height()*(this.MaxWeek+1); }, fGetCalendarTitle: function(){ var title = "<ul class=\'calendar-title-pas calendar-pas\'><li>日</li><li>一</li><li>二</li><li>三</li><li>四</li><li>五</li><li>六</li></ul><div class=\'calendar-content-pas\'></div>"; return title; }, fRender: function(year,month,day){ var tpl = this.fLoadTemplate(year,month,day); $(\'.calendar-content-pas\').html(tpl); if(this.type == this._config.WEEK){ this.weekHeight = $(".calendar-week-pas").height(); } this._fBindEvt(); }, /** * 日历模板数据 month 0-11, day 1-31 */ fLoadTemplate: function(year,month,day){ var dataType = this.type, tpl =""; var showMonth = this.CurMonth + 1; var data = this.MonthData; if(dataType == this._config.MONTH){ tpl = "<div class=\'calendar-month-div\' style=margin-top:"+ this._initTop+"px" +">"+"<p class=\'calendar-showmonth-pas\'>"+this.fTransfNum2Upper(showMonth)+"月</p><ul class=\'calendar-month-pas calendar-pas\'>"; var lis = this.fGetLiTpl(data,year,month); tpl = tpl + lis +"</ul></div>"; }else if(dataType == this._config.WEEK){ var left = -(this.WeekIndex-1)*this._width+"px"; var ul_wid = (this._width / 7) * data.length + \'px\'; tpl = "<ul class=\'calendar-week-pas calendar-pas\' style=width:"+ ul_wid +";margin-left:"+left+ ">"; tpl = tpl + this.fGetLiTpl(data,year,month)+"</ul>"; } return tpl; }, //填充每一行的数据 fGetLiTpl: function(data,year,month){ var li_tpl = \'\'; for(var i=0,len=data.length;i<len;i++){ var rec = data[i]; var fillYear = rec.year,fillMonth = rec.month, fillDay = rec.day; var isToday = this.fIsCurrentDay(fillYear,fillMonth,fillDay); var activeDay = isToday ? fillDay: null; var m = fillMonth + 1; var attr = fillYear+"-"+m+"-"+ fillDay; var classItem = fillMonth == this.CurMonth ? \'\' :\'unvisibleItem\'; classItem += fillDay == activeDay ? " activeDay" : " normalDay"; fillDay = isToday ? "今" : fillDay; var li_wid = $(".calendar-content-pas").width() / 7 +"px"; li_tpl += "<li class=\'"+classItem+"\'"+ " calendar-date=\'"+attr+"\'"+" style=width:"+li_wid+"><a href=\'javascript:void(0)\'>"+fillDay+"<i></i></a></li>"; } return li_tpl; }, _fBindEvt: function(){ var self = this; $(".calendar-content-pas li ").on("click",function(){ var clickObj = this; self._fSelectDate(clickObj); }); var swipeObj = new Swipe(".calendar-week-pas"); swipeObj.bind("swipeLeft",function(){ self.fGoNextWeek(); }); swipeObj.bind("swipeRight",function(){ self.fGoPrevWeek(); }); swipeObj.bind("swipeDown",function(){ if(self.type==self._config.MONTH){ //已经是月数据 return; } console.log("swipeDown...显示月数据"); self.fShowMonthData(); if(typeof self.callback.slideDown == \'function\'){ self.callback.slideDown(); } }); var monthSwipe = new Swipe(".calendar-month-pas"); monthSwipe.bind("swipeUp",function(){ if(self.type==self._config.WEEK){ //已经是周数据 多次上滑操作 只更新一次 return; } console.log("swipeUp...显示周数据"); self.fShowWeekData(); }); }, //滑动到上一周数据 fGoPrevWeek: function(){ if(this.WeekIndex <= 1){ return; } this.WeekIndex--; var li_wid = this._width / 7; var left = -(this.WeekIndex-1)*(li_wid*7); this.fSlideEffect(".calendar-week-pas","margin-left"); $(".calendar-week-pas").css("margin-left",left+"px"); }, fGoNextWeek: function(){ if(this.WeekIndex >= this.MaxWeek){ return; } this.WeekIndex++; var li_wid = this._width / 7; var left = -(this.WeekIndex-1)*(li_wid*7); this.fSlideEffect(".calendar-week-pas","margin-left"); $(".calendar-week-pas").css("margin-left",left+"px"); }, //下拉 显示月历 fShowMonthData: function(){ this.type = this._config.MONTH; this.fUpdateCalendar(this.CurYear,this.CurMonth,this.CurDay); var top = -$(".calendar-month-div").height()+"px"; $(".calendar-month-div").css("margin-top",top); this.fSlideEffect(".calendar-month-div","margin-top"); $(".calendar-month-div").css("margin-top","0"); }, //周 日历 fShowWeekData: function(){ this.type = this._config.WEEK; var arr = this.selectedDate.split("-"); var year = parseInt(arr[0]), month = parseInt(arr[1])-1,day = parseInt(arr[2]); this.WeekIndex = this.fCalculatePos(this.MonthData,year,month,day); var self = this; var top = -($(".calendar-month-div").height()-this.weekHeight)+"px"; $(".calendar-month-div").css("margin-top",top); var time = this._config.SlideTime; setTimeout(function(){ $(".calendar-month-div").remove(); console.log(\'slide end.\'); console.log(\'当前类型\',self.type); if(self.type==self._config.WEEK){ self.fUpdateCalendar(year,month,day); } },time); }, //更新日历 fUpdateCalendar: function(year,month,day){ console.log(\'更新日历,日历类型\',this.type); this.fRender(year,month,day); this.fRenderEventDate(); this.fRenderSelected(this.selectedDate); }, //在某个元素上使用滑动效果 fSlideEffect: function(element,attr){ var time = this._config.SlideTime; var style = { \'-webkit-transition\':attr +" "+time+\'ms\', \'transition\':attr + " "+time+\'ms\', \'-webkit-backface-visibility\': \'hidden\' }; $(element).css(style); }, //绑定自定义事件 对外暴露 fBind: function(evtName,callback){ if(evtName==\'dateChange\'){ this.callback.dateChange = callback; }else if(evtName==\'slideDown\'){ this.callback.slideDown = callback; } }, //计算周 的位置 fCalculatePos: function(data,year,month,day){ var weekIndex = 1; for(var i=0,len=data.length;i<len;i++){ var rec = data[i]; var fillYear = rec.year,fillMonth = rec.month, fillDay = rec.day; if(fillYear==year && fillMonth==month && fillDay==day){ weekIndex = Math.ceil( (i+1) / 7); } } return weekIndex; }, //选择时间 _fSelectDate: function(clickObj){ if($(clickObj).hasClass(\'unvisibleItem\')){ return;} var date = $(clickObj).attr(\'calendar-date\'); if(this.selectedDate != date){ this.selectedDate = date; this.fRenderSelected(date); if(typeof this.callback.dateChange ==\'function\'){ this.callback.dateChange(date); } } }, //渲染选中日期 fRenderSelected: function(selectedDate){ var self = this; $(".calendar-content-pas li").each(function(){ var date = $(this).attr("calendar-date"); var showday = date.split("-")[2]; if($(this).hasClass(\'activeDay\') && selectedDate != date){ $(this).removeClass(\'activeDay\'); $(this).children(\'a\').eq(0).html(showday+"<i></i>"); } if(selectedDate == date){ $(this).addClass(\'activeDay\'); var arr = date.split("-"),year = arr[0], month = arr[1]-1,day = arr[2]; var isCurrentDay = self.fIsCurrentDay(year,month,day); if(isCurrentDay){ $(this).children(\'a\').eq(0).html("今<i></i>"); } } }); }, //获取日历模板 一个月的数据信息 fGetCalendarData_month: function(year,month){ var monthInfo = this.fGetMonthInfo(year,month); var firstDay = monthInfo.firstDay; var lastDay = monthInfo.lastDay; var totalDays = monthInfo.totalDays; var fillData = []; //{year:,month:0-11,day:1-31} var prevData = firstDay!==0 ? this._fGetPrevData(firstDay,year,month) : []; fillData = fillData.concat(prevData); for(var k=1;k<totalDays+1;k++){ fillData.push({year:year,month:month,day:k}); } var nextData = lastDay!==6 ? this._fGetNextData(lastDay,year,month) : []; fillData = fillData.concat(nextData); return fillData; }, // 月日历模板 不足的用上一个月的补充 _fGetPrevData: function(firstDay,year,month){ var prevData = []; var lastMonth_info = this.fGetDaysOfPrevMonth(year,month); var totalDays_last = lastMonth_info.totalDays; for(var i=firstDay-1;i>=0;i--){ var _prevDay = totalDays_last - i; var obj = {year:lastMonth_info.year,month:lastMonth_info.month,day:_prevDay}; prevData.push(obj); } return prevData; }, _fGetNextData: function(lastDay,year,month){ var nextData = []; var nextMonth_info = this.fGetDaysOfNextMonth(year,month); for(var j=1;j<7-lastDay;j++){ //最后一天 之后的 没有数据的 var obj = {year:nextMonth_info.year,month:nextMonth_info.month,day:j}; nextData.push(obj); } return nextData; }, //有事件的日期下方加点号 dateArr[\'20161125\',\'\',....] fAddEvtCircle: function(dateArr){ this.eventDate = dateArr; this.fRenderEventDate(); }, //有事件的日期 加小圆点 fRenderEventDate: function(){ var dateArr = this.eventDate; $(".calendar-content-pas li").each(function(){ var date = $(this).attr("calendar-date"); if($.inArray(date, dateArr)!=-1){ $(this).addClass(\'symbol\'); } }); }, /** * 获取某一个月的天数、第一天 最后一天周几 new Date(xxxx,xx,0) 0 即返回上一个月的最后一天 * @param {Number} year * @param {Number} month 月份数 0-11 */ fGetDaysOfMonth: function(year,month){ if(month >11 || month < 0){ return;} var d = new Date(year,month+1,0); //上一个月的最后一天 var days = d.getDate(); //天数 return days; }, //获取上一个月的天数 fGetDaysOfPrevMonth: function(year,month){ if(month===0){ year = year -1; //获取上一年的最后一个月 month = 11; }else{ month = month - 1; } var days = this.fGetDaysOfMonth(year,month); return {totalDays:days,year:year,month:month}; }, // 获取下一个月的天数 fGetDaysOfNextMonth: function(year,month){ if(month===11){ year = year + 1; month = 0; }else{ month = month + 1; } var days = this.fGetDaysOfMonth(year,month); return {totalDays:days,year:year,month:month}; }, //获取月份的信息 总天数,第一天 最后一天周几 fGetMonthInfo: function(year,month){ if(month >11 || month < 0){ return;} var d = new Date(year,month+1,0); //上一个月的最后一天 var days = d.getDate(); //天数 var lastDay = d.getDay(); var firstDay = this.fGetWeekOfDay(year,month,1); //第一天周几 return {firstDay:firstDay,lastDay:lastDay,totalDays:days}; }, // 获取某一天 周几 month 0-11 day 1-31 fGetWeekOfDay: function(year,month,day){ if(day > 31 || day < 1){ return; } var d = new Date(year,month,day); return d.getDay(); //星期几 }, //判断是否是当前日期 fIsCurrentDay: function(year,month,day){ var d = new Date(); return d.getFullYear() == year && d.getMonth() == month && day == d.getDate(); }, fTransfNum2Upper : function(i){ i = i.toString(); var NumberArr = ["","一","二","三","四","五","六","七","八","九","十"]; var result = i <= 10 ? NumberArr[i] : "十"+NumberArr[i.split("")[1]]; return result; } }; module.exports = Calendar; });
以上是关于日历实现的主要内容,如果未能解决你的问题,请参考以下文章