1. 程式人生 > >日歷實現

日歷實現

sof 一次 selector () rip swipe sym fun 下一個

日歷要實現下面兩種效果,圖一是周數據,左右滑動切換不同周的數據。下拉後,切換成月數據即圖二。在月數據視圖下,上滑切換成周數據。

技術分享

技術分享

/**
 * 日歷插件 依賴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; });

日歷實現