zoukankan      html  css  js  c++  java
  • 日历实现

     日历要实现下面两种效果,图一是周数据,左右滑动切换不同周的数据。下拉后,切换成月数据即图二。在月数据视图下,上滑切换成周数据。

     

    /**
     * 日历插件 依赖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="+ 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="+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;
    });
  • 相关阅读:
    OC核心语法之构造方法、Category分类、类的本质、description和SEL
    OC核心语法之NSString、点语法、成员变量作用域、@property和@synthesize
    OC基本语法、类和对象、三大特性
    C语言基础之结构体、枚举、预处理、typedef的使用
    C语言基础之复杂数据类型的学习
    v880 debug
    JQuery的一些简单操作02
    JQuery的一些简单操作01
    学习SVG系列(5):SVG渐变
    学习SVG系列(4):SVG滤镜效果
  • 原文地址:https://www.cnblogs.com/lydialee/p/7083304.html
Copyright © 2011-2022 走看看