小程序自定义日历效果

重点在于将数个月的日期拆分重组,然后再统一以月为输出。详细操作代码注释有说明。

<view> <!--整体日期循环部分 --> <block wx:for="{{allMan}}" wx:for-item="item" > <view> <view> <view>{{item.year || "--"}} 年 {{item.Month || "--"}} 月</view> </view> <!--展示星期几的头部 --> <view> <view wx:for="{{weeks_ch}}" wx:key="{{index}}" data-idx="{{index}}">{{item}}</view> </view> <view> <view wx:for="{{item.empyt}}" wx:key="{{index}}" data-idx="{{index}}"> </view> <!--循环日期 --> <block wx:for="{{item.day}}" wx:for-item="item" wx:key="{{index}}"> <view data-idx="{{index}}" data-dayz="{{item.dayZ}}" bindtap="{{item.canChoosed ? 'tapDayItemX' : ''}}"> <view> {{item.today}} </view> </view> </block> </view> </view> </block> </view>

.js:

let choose_year = null,//选择的年 choose_month = null;//选择的月 let clickNum=new Array();//点击日期的次数,做显示判断处理 let date = new Date(); let cur_year = date.getFullYear(); let cur_month = date.getMonth() + 1; let weeks_ch = ['日', '一', '二', '三', '四', '五', '六']; //日历的显示 let allMan = new Array();//循环总日历容器 let haveClickNum=false;//是否可点击选择日期 let havInitDate = false;//是否已经重置数据 let conf = {//拿去给Page onLoad() { if (allMan.length != 0) {//重新进入界面发现已经有数据,直接渲染 havInitDate = false; clickNum = new Array(); haveClickNum = true; this.setData({ allMan, weeks_ch }) }else{ allMan = new Array();//非常重要的主输出,计算好的每月数据都合拼在里面 clickNum = new Array(); let that = this; let empytGrids = this.calculateEmptyGrids(cur_year, cur_month);//计算空格 let days = this.calculateDays(cur_year, cur_month);//计算日期总数 let DogDays = { year: cur_year, Month: cur_month, empyt: empytGrids, day: days };//组装年、月、星期一前的空格、日 allMan.push(DogDays); let newMonth = cur_month + 1; let newYear = cur_year; if (newMonth > 12) {//新年重置1月份 newYear = cur_year + 1; newMonth = 1; } let empytGridsTwos = this.calculateEmptyGridsTwo(newYear, newMonth);//计算新月份的空格 let dayTwos = this.calculateDaysTwo(newYear, newMonth);//计算日期总数 let catDays = { year: newYear, Month: newMonth, empyt: empytGridsTwos, day: dayTwos }; allMan.push(catDays); let sakura = days.concat(dayTwos);//将存放日期的内容统一合并为数组,单独处理是否可选等展示状态,属于中间件数组 let isTrue = new Array();//存放可选 for (var i = 0; i < sakura.length; i++) {//循环处理 if (sakura[i].canChoosed == true) { isTrue.push(sakura[i]); } else { continue } } let addMoreMonth = function () {//添加更多的月份 let isTrue = new Array();//是否可选的日期数组,为N个月等可选日期总日输做判断 for (var i = 0; i < sakura.length; i++) { if (sakura[i].canChoosed == true) { isTrue.push(sakura[i]); } else { continue } } let newMonthThree = newMonth + 1; let newYearThree = newYear; if (newMonthThree > 12) { newYearThree = newYear + 1; newMonthThree = 1; } let empytGridsThree = that.calculateEmptyGridsTwo(newYearThree, newMonthThree);//计算空格 let dayThree = that.calculateDaysTwo(newYearThree, newMonthThree, 91 - isTrue.length);//计算日期总数,61减,今天不算 let duckDays = { year: newYearThree, Month: newMonthThree, empyt: empytGridsThree, day: dayThree }; sakura = sakura.concat(dayThree); allMan.push(duckDays); if (parseInt(91 - isTrue.length) > parseInt(dayThree.length)) {//第n个月是否足够显示需要的可选日期长度 for (var i = 0; i < dayThree.length; i++) { if (dayThree[i].canChoosed == true) { isTrue.push(dayThree[i]); } else { continue } } let newMonthFour = newMonthThree + 1; let newYearFour = newYearThree; if (newMonthFour > 12) { newYearFour = newYearThree + 1; newMonthFour = 1; } let empytGridsFour = that.calculateEmptyGridsTwo(newYearFour, newMonthFour);//计算空格 let dayFour = that.calculateDaysTwo(newYearFour, newMonthFour, 91 - isTrue.length);//计算日期总数,61减,今天不算 let wolfDays = { year: newYearFour, Month: newMonthFour, empyt: empytGridsFour, day: dayFour }; sakura = sakura.concat(dayFour); allMan.push(wolfDays); } else {//不足够继续增加第n+1个月 let newMonthFour = newMonthThree + 1; let newYearFour = newYearThree; if (newMonthFour > 12) { newYearFour = newYearThree + 1; newMonthFour = 1; } let empytGridsFour = that.calculateEmptyGridsTwo(newYearFour, newMonthFour);//计算空格 let dayFour = that.calculateDaysTwo(newYearFour, newMonthFour, -1);//计算日期总数,61减,今天不算 let wolfDays = { year: newYearFour, Month: newMonthFour, empyt: empytGridsFour, day: dayFour }; sakura = sakura.concat(dayFour); allMan.push(wolfDays); } } if (isTrue.length < 90) { addMoreMonth(); } this.setData({ allMan, weeks_ch }) } }, onShow: function () { // console.log(allMan); // allMan = new Array();//循环总日历容器 // 页面显示 }, getThisMonthDays(year, month) { return new Date(year, month, 0).getDate(); }, getFirstDayOfWeek(year, month) { return new Date(Date.UTC(year, month - 1, 1)).getDay(); }, calculateEmptyGrids(year, month) { let firstDayOfWeek = this.getFirstDayOfWeek(year, month); let empytGrids = []; if (firstDayOfWeek > 0) { for (let i = 0; i < firstDayOfWeek; i++) { empytGrids.push(i); } } return (empytGrids); }, calculateEmptyGridsTwo(year, month) { let firstDayOfWeek = this.getFirstDayOfWeek(year, month); let empytGridsTwo = []; if (firstDayOfWeek > 0) { for (let i = 0; i < firstDayOfWeek; i++) { empytGridsTwo.push(i); } } return (empytGridsTwo); }, calculateDays(year, month) { let days = []; let date = new Date(); let thisMonthDays = this.getThisMonthDays(year, month);//这个月的总日数 let d = date.getDate(); let weeHours=date.getHours(); let zaa = year+month+date.getDate(); for (let i = 1; i <= thisMonthDays; i++) { if (year+month+i == zaa){ days.push({ day: i, dayZ: cur_year+"-"+cur_month+"-"+i, choosed: false, canChoosed: true, today: i }); } else if (year + month + i < zaa){ if (weeHours <= 2 && year + month + i == zaa-1){//加个判断:是否凌晨3点之前,是的话就拿日期集-1来对前一日可选 days.push({ day: i, dayZ: cur_year + "-" + cur_month + "-" + i, choosed: false, canChoosed: true, today: i }); }else{ days.push({ day: i, dayZ: cur_year + "-" + cur_month + "-" + i, choosed: false, canChoosed: false, today: i }); } } else{ days.push({ day: i, dayZ: cur_year + "-" + cur_month + "-" + i, choosed: false, canChoosed: true, today: i }); } } this.setData({ // days }); return (days); }, calculateDaysTwo(year, month,takeNum) { let days_two = []; let date = new Date(); let thisMonthDays = this.getThisMonthDays(year, month); let d = date.getDate(); let zaa = year+"-"+month+"-"+date.getDate(); if (takeNum) { console.log(takeNum); } for (let i = 1; i <= thisMonthDays; i++) { takeNum--; if (takeNum<0){ days_two.push({ day: i, dayZ: year + "-" + month + "-" + i, choosed: false, canChoosed: false, today: i }); }else{ days_two.push({ day: i, dayZ: year + "-" + month + "-" + i, choosed: false, canChoosed: true, today: i }); } } this.setData({ // days_two }); return (days_two); }, handleCalendar(e) { let handle = e.currentTarget.dataset.handle; let cur_year = this.data.cur_year; let cur_month = this.data.cur_month; if (handle === 'prev') { let newMonth = cur_month - 1; let newYear = cur_year; if (newMonth < 1) { newYear = cur_year - 1; newMonth = 12; } this.calculateDays(newYear, newMonth); this.calculateEmptyGrids(newYear, newMonth); this.setData({ cur_year: newYear, cur_month: newMonth }); } else { let newMonth = cur_month + 1; let newYear = cur_year; if (newMonth > 12) { newYear = cur_year + 1; newMonth = 1; } this.calculateDays(newYear, newMonth); this.calculateEmptyGrids(newYear, newMonth); this.setData({ cur_year: newYear, cur_month: newMonth }); } }, tapDayItemX(e) {//点击日期处理 if (clickNum.length >= 2)//点了两次,不可再点 return; if (haveClickNum){//是否已经选择过日期 this.initChosedDate();//重置选择过的样式 let dayZ = e.currentTarget.dataset.dayz; for (let i = 0; i < allMan.length; i++) { let li = allMan[i].day; for (let k = 0; k < li.length; k++) { if (li[k].dayZ == dayZ) { if (clickNum.length == 0) { li[k].startDay = true; } if (clickNum.length == 1) { li[k].endDay = true; } }else{//已选择的区间日期重置 li[k].dependence = false; } } } this.setData({//渲染 allMan }) clickNum.push(integerDate(dayZ));//格式化日期,准备拿去比较函数处理 }else{//第一次进入生命周期,从没选择过的处理 let dayZ = e.currentTarget.dataset.dayz; for (let i = 0; i < allMan.length; i++) { let li = allMan[i].day; for (let k = 0; k < li.length; k++) { if (li[k].dayZ == dayZ) { if (clickNum.length == 0) { li[k].startDay = true; } if (clickNum.length == 1) { li[k].endDay = true; } } } } this.setData({//渲染 allMan }) clickNum.push(integerDate(dayZ));//格式化日期,准备拿去比较函数处理 } if (clickNum.length < 2)//点击了第二次,进行teturn下面的渲染操作 return clickNum.sort(compare);//拿去比较函数处理 let dayDiff = GetDateDiff(clickNum[0], clickNum[1]); let startDay = clickNum[0];//第一位为开始日期 let startMonth = new Date(clickNum[0]).getMonth() + 1;//开始的月,跨月显示用 let formatStartDay = new Date(clickNum[0]).getFullYear() + '-' + startMonth + '-' + new Date(clickNum[0]).getDate();//格式化开始日期,后面用于给总输出allman做判断 let endMonth = new Date(clickNum[1]).getMonth() + 1;//结束的月,跨月显示用 let formatEndDay = new Date(clickNum[1]).getFullYear() + '-' + endMonth + '-' + new Date(clickNum[1]).getDate();//格式化结束日期,后面用于给总输出allman做判断 let endDay = clickNum[1];//第二位为结束日期 for (let i = 0; i < allMan.length; i++) {//循环总输出allMan数组得出每月的日期数组,将开始、结束日期带进去做改变显示状态处理 let li = allMan[i].day; for (let k = 0; k < li.length; k++) {//每个月的日期数组,拆分更细 let foxDay = integerDate(li[k].dayZ); if (startDay < foxDay && foxDay < endDay){ li[k].dependence = true;//已选择的区间日期 } else if (li[k].dayZ == formatStartDay){//开始日期状态处理 li[k].startDay = true; li[k].endDay = false; } else if (li[k].dayZ == formatEndDay) {//结束日期状态处理 li[k].startDay = false; li[k].endDay = true; } } } this.setData({//再渲染 allMan }) wx.navigateBack({ delta: 1, }) }, initChosedDate(){ if (havInitDate) return for (let i = 0; i < allMan.length; i++) { let li = allMan[i].day; for (let k = 0; k < li.length; k++) { li[k].startDay = false; li[k].endDay = false; } } havInitDate=true; }, }; Page(conf); let compare = function (x, y) {//比较函数,那个日期谁先谁后,star/end if (x < y) { return -1; } else if (x > y) { return 1; } else { return 0; } } function GetDateDiff(startDate, endDate) { let dates = Math.abs((startDate - endDate)) / (1000 * 60 * 60 * 24); return dates; } function integerDate(choseDate){ let integerDay = new Date(Date.parse(choseDate.replace(/-/g, "https://www.jb51.net/"))).getTime(); return integerDay; }

.wxss:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/3caaec319b79df79aaf27881648a2d6c.html