开发招聘助手的有个页面需要画日历,因为开发比较急,想换个方式去实现功能的,但是想想自己本来就打算写个日历,这次未必不是个很好的机会啊~所以也就花了一天整了个日历
先看效果:
默认打开是定位到当月当天,本日之前的天数灰色字体标识
点击按钮切换月份
左右滑动切换当月的周
说一下主要的实现原理吧:
在做之前参考了很多的代码,但是不知道为什么,心里面总觉得这样去实现太麻烦了,而且可能由于资历不够,看别人的代码也比较难懂。。。
所以就自己想了下:
这里主要是通过二维数组ng-repeat实现的,给出
$scope.days = [ [ {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""} ], [ {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""} ], [ {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""} ], [ {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""} ], [ {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""} ], [ {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""}, {"date": "", "check": false, "year": "", "month": ""} ] ];
前端代码:
<ion-slide> <table> <tbody> <tr> <th>日</th> <th>一</th> <th>二</th> <th>三</th> <th>四</th> <th>五</th> <th>六</th> </tr> <tr ng-repeat="weeek in [4,5]" ng-init="index = $index+4"> <td ng-repeat="day in days[index] track by $index" ng-click="choiceToday(day)"> <div ng-class="{true:'yimianshi'}[day.date == currentDate]"></div> <div ng-class="{true:'checked'}[day.check]"> <span ng-class="{true:'spanColor'}[day.smallToday]">{{day.date}}</span> </div> </td> </tr> </tbody> </table> </ion-slide>
本想用三维数组,以为这个ion-slide是顾哥的建议,之前都已完成60%,所以就没有做太多的修改
还有给$scope.days赋值的的一个对象数组:
var valueArr = new Array();//用于给$scope.days赋值的数组
下面将以功能化去展现代码:
首先日历的初始化:
//初始化日期操作 function initDate() { myDate = new Date(); $scope.year = myDate.getFullYear(); $scope.month = myDate.getMonth() + 1; $scope.date = myDate.getDate(); $scope.currentDate = $scope.date; $scope.currentMonth = $scope.month; $scope.headerMonth = $scope.month; $scope.currentEnMonth = monthShort($scope.month); $scope.currentYear = $scope.year; day = myDate.getDay(); num = day - ($scope.date % 7 - 1); if (ROOTCONFIG) { console.log("myDate = " + myDate); console.log($scope.year + "年" + $scope.month + "月" + $scope.date + "日 星期" + day); console.log("本月第一天星期" + num); } }
判断每一个月多少天:
这个比较简单
function thisMonthDays(month, year) { var end = 0; switch (month) { case 1: end = 31; break; case 2: if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))end = 29; else end = 28; break; case 3: end = 31; break; case 4: end = 30; break; case 5: end = 31; break; case 6: end = 30; break; case 7: end = 31; break; case 8: end = 31; break; case 9: end = 30; break; case 10: end = 31; break; case 11: end = 30; break; case 12: end = 31; break; } return end; }
为数组赋值:
function initValueArr(year, month, num, valueArr) { $scope.enMonth = monthShort(month); var newDay = 1;//每月第一天 //var newMonthDay = 1; var templateMonth = $scope.month - 1; var templateYear = $scope.year; if (templateMonth == 0) { templateMonth = 12; templateYear = $scope.year - 1; } var preMon = thisMonthDays(templateMonth, year);//上一个月天数 var currentMon = thisMonthDays(month, year);//本月天数 //num之前的赋值 for (var i = num - 1; i >= 0; i--) { var obj = {}; //obj.date = preMon-i; //console.log(obj.date); //obj.month = templateMonth; //obj.year = templateYear; obj.data = ""; obj.month = ""; obj.year = ""; valueArr.push(obj); } //num以后的赋值操作 for (var i = num; i < 42; i++) { var obj = {}; obj.date = newDay++; obj.month = $scope.month; obj.year = $scope.year; //如果大于半月的天数以后将从1开始算起 if (obj.date > currentMon) { //newDay = 1; //obj.date = newDay++; //$scope.month += 1; //if ($scope.month > 12) { // $scope.month = 1; // obj.month = $scope.month; // $scope.year += 1; // obj.year = $scope.year; //} obj.date = ""; obj.month = ""; obj.year = ""; } valueArr.push(obj); } console.log(angular.toJson(valueArr)); }
注释的部分是因为最终决定在当前月份中不显示前一个月和后一个月的日期,由于日期的颜色只区分今天的之前和以后,所以这里显示出之前的会比较乱。
对象数组给二维对象数组赋值的函数
function setDaysValue(arr) { for (var i = 0; i < 6; i++) { for (var j = 0; j < 7; j++) { $scope.days[i][j].date = arr[0].date; $scope.days[i][j].year = arr[0].year; $scope.days[i][j].month = arr[0].month; if ($scope.days[i][j].date == $scope.currentDate) { if ($scope.days[i][j].month == $scope.currentMonth) { if ($scope.days[i][j].year == $scope.currentYear) { console.log($scope.currentYear); console.log($scope.currentMonth); console.log($scope.currentDate); console.log("yanglei" + angular.toJson($scope.days[i][j])); $scope.days[i][j].check = true; if (i > 1 && i < 4) { $scope.myIndex = 1; } else { $scope.myIndex = 2; } } } } if ($scope.days[i][j].year > $scope.currentYear) { $scope.days[i][j].smallToday = false; } else { if ($scope.days[i][j].month > $scope.currentMonth) { $scope.days[i][j].smallToday = false; } else if ($scope.days[i][j].month < $scope.currentMonth) { $scope.days[i][j].smallToday = true; } else { if ($scope.days[i][j].date >= $scope.currentDate) { $scope.days[i][j].smallToday = false; } else { $scope.days[i][j].smallToday = true; } } } arr.shift(); } } }
点击跳转下一个月和上一个月的操作
其实我觉得这里是可以抽离封装出来的,不至于代码的这么大重复性
后续再做优化
$scope.nextMon = function () { //var myDate = new Date(); var nian = myDate.getFullYear(); var yue = myDate.getMonth(); yue += 2; if (yue == 13) { nian++; yue = 1; } var ri = "1"; var str = nian + " " + yue + " " + ri; myDate = new Date(str); $scope.year = myDate.getFullYear(); $scope.month = myDate.getMonth() + 1; $scope.date = myDate.getDate(); $scope.headerMonth = $scope.month; day = myDate.getDay(); num = day - ($scope.date % 7 - 1); initValueArr($scope.year, $scope.month, num, valueArr); for (var i = 0; i < 6; i++) { for (var j = 0; j < 7; j++) { $scope.days[i][j].check = false; } } setDaysValue(valueArr); //if($scope.month != $scope.currentMonth){ // $scope.myIndex = 0; //} $ionicSlideBoxDelegate.slide(0); if (ROOTCONFIG) { console.log("myDate = " + myDate); console.log($scope.year + "年" + $scope.month + "月" + $scope.date + "日 星期" + day); console.log("本月第一天星期" + num); } }; //上一个月 $scope.preMon = function () { var nian = myDate.getFullYear(); var yue = myDate.getMonth(); if (yue == 0) { nian--; yue = 12; } var ri = "01"; var str = nian + " " + yue + " " + ri; myDate = new Date(str); $scope.year = myDate.getFullYear(); $scope.month = myDate.getMonth() + 1; $scope.date = myDate.getDate();//获取日期 $scope.headerMonth = $scope.month; day = myDate.getDay(); num = day - ($scope.date % 7 - 1); initValueArr($scope.year, $scope.month, num, valueArr); for (var i = 0; i < 6; i++) { for (var j = 0; j < 7; j++) { $scope.days[i][j].check = false; } } setDaysValue(valueArr); //if($scope.month != $scope.currentMonth){ // $scope.myIndex = 0; //} $ionicSlideBoxDelegate.slide(0); if (ROOTCONFIG) { console.log("myDate = " + myDate); console.log($scope.year + "年" + $scope.month + "月" + $scope.date + "日 星期" + day); console.log("本月第一天星期" + num); } };
对了,这其中还有个月份的转化下(貌似并没有什么好说的哦):
//月份的英语缩写 function monthShort(month) { var enMonth = ""; switch (month) { case 1: enMonth = "Jan"; break; case 2: enMonth = "Feb"; break; case 3: enMonth = "Mar"; break; case 4: enMonth = "Apr"; break; case 5: enMonth = "May"; break; case 6: enMonth = "Jun"; break; case 7: enMonth = "Jul"; break; case 8: enMonth = "Aug"; break; case 9: enMonth = "Sep"; break; case 10: enMonth = "Oct"; break; case 11: enMonth = "Nov"; break; case 12: enMonth = "Dec"; break; } return enMonth; }
其中还有各种函数的调用
initDate(); initValueArr($scope.year, $scope.month, num, valueArr); setDaysValue(valueArr);
就这样,一个简单的日历就出来了
感觉很多东西还是要自己去尝试,看别人的代码怎么怎么的,其实也不是一气呵成的。
慢慢来~