小程序自定义日历效果


Posted in Javascript onDecember 29, 2018

本文实例为大家分享了小程序自定义日历展示的具体代码,供大家参考,具体内容如下

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

<view class="flex box box-tb box-align-center">
<!--整体日期循环部分 -->
<block wx:for="{{allMan}}" wx:for-item="item" >
 <view class="calendar pink-color box box-tb">
  <view class="top-handle fs28 box box-lr box-align-center box-pack-center">
   <view class="date-area box box-lr box-align-center box-pack-center years-month">{{item.year || "--"}} 年 {{item.Month || "--"}} 月</view>
  </view>
  <!--展示星期几的头部 -->
  <view class="weeks box box-lr box-pack-center box-align-center day-week">
   <view class="flex week fs28" wx:for="{{weeks_ch}}" wx:key="{{index}}" data-idx="{{index}}">{{item}}</view>
  </view>
  <view class="days box box-lr box-wrap">
   <view class="grid white-color box box-align-center box-pack-center" wx:for="{{item.empyt}}" wx:key="{{index}}" data-idx="{{index}}">
   </view>
   <!--循环日期 -->
   <block wx:for="{{item.day}}" wx:for-item="item" wx:key="{{index}}">
    <view class="grid white-color box box-align-center box-pack-center" data-idx="{{index}}" data-dayz="{{item.dayZ}}" bindtap="{{item.canChoosed ? 'tapDayItemX' : ''}}">
    <view class="day {{item.dependence ? 'border-instinct pink-bg' : ''}} {{item.startDay ? 'border-radius dependence-bg' : ''}} {{item.endDay ? 'border-right-radius dependence-bg' : ''}} {{item.canChoosed ? '' : 'grays'}} box box-align-center box-pack-center">
     {{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, "/"))).getTime();
 return integerDay;
}

.wxss:

/* pages/calendar/calendar.wxss */
.top-handle {
 height: 80rpx;
}
.prev {
 text-align: right;
 height: 80rpx;
}
.next {
 height: 80rpx;
}
.prev-handle {
 width: 80rpx;
 height: 100%;
}
.next-handle {
 width: 80rpx;
 height: 100%;
}
.date-area {
 width: 50%;
 height: 80rpx;
 text-align: center;
}
.weeks {
 height: 50rpx;
 line-height: 50rpx;
 opacity: 0.5
}
.week {
 text-align: center;
}
.days {
 height: 500rpx;
}
.grid {
 width: 107.1428571429rpx;
}
.day {
 width: 100%;
 height: 100%;
 color: #000;
 font-size: 26rpx;
 font-weight: 200;
}
.border-instinct{
 position: relative;
 left: 0;
 top: 0;
 color: #fff;
}
.border-radius {
 border-radius:5px 0 0 5px;
 position: relative;
 left: 0;
 top: 0;
 color: #fff;
}
.border-right-radius {
 border-radius:0 5px 5px 0;
 position: relative;
 left: 0;
 top: 0;
 color: #fff;
}
.pink-bg {
 background-color: #ffe5b4;
  color: #f6ac1d;
}
.dependence-bg {
 background-color: #d9246b;
}
.purple-bg {
 background-color: #b8b8f1;
}
 
.right-triangle::after {
 content: "";
 display: block;
 width: 0;
 height: 0;
 border: 15rpx solid transparent;
 border-left-color: #ff629a;
 position: absolute;
 right: -22rpx;
 top: 18rpx;
}
.left-triangle::before {
 content: "";
 display: block;
 width: 0;
 height: 0;
 border: 15rpx solid transparent;
 border-right-color: #ff629a;
 position: absolute;
 left: -22rpx;
 top: 18rpx;
}
.tips {
 text-align: center;
 margin-top: 20rpx;
 margin-bottom: 20rpx;
}
.types {
 background-color: #ffedf4;
 height: 50rpx;
}
.type-dot {
 width: 25rpx;
 height: 25rpx;
 border-radius: 50%;
 margin-right: 10rpx;
}
.type-dot-ymq {
 color:#FF7CA0;
 background-color: #FF7CA0;
}
.type-dot-ycq {
 color: rgb(255, 200, 202);
 background-color: rgb(255, 200, 202);
}
.type-dot-aqq {
 color: rgb(118, 191, 92);
 background-color: rgb(118, 191, 92);
}
.type-dot-yyq {
 color: #FF7CA0;
 background-color: #FF7CA0;
}
.type-dot-plr {
 color: rgb(211, 189, 215);
 background-color: rgb(211, 189, 215);
}
.types-desc {
 padding: 0 20rpx;
}
.type-name {
 margin-top: 50rpx;
 margin-bottom: 30rpx;
}
.type-desc {
 padding: 0 35rpx;
 line-height: 38rpx;
}
.explain {
 border-top: 1px solid #eee;
 width: 90%;
 margin: 20rpx 5% 20rpx 5%;
 padding: 20rpx 0;
}
.explain-title {
 font-weight: bold;
 margin-bottom: 15rpx;
}
.explain-item {
 padding: 8rpx 20rpx;
 color: #fff;
}
.left-border-radius {
 border-top-left-radius: 20rpx;
 border-bottom-left-radius: 20rpx;
}
.right-border-radius {
 border-top-right-radius: 20rpx;
 border-bottom-right-radius: 20rpx;
}
.picker-btns {
 height: 120rpx;
 line-height: 120rpx;
 border-bottom: 1rpx solid #FF7CA0;
}
.picker-confirm {
 margin-right: 50rpx;
}
.picker-cancel {
 margin-left: 50rpx;
}
.picker-view {
 color:#FF7CA0;
 text-align: center;
}
 
.box {
 display: flex;
}
 
.box-lr {
 flex-direction: row;
}
 
.box-rl {
 flex-direction: row-reverse;
}
 
.box-tb {
 flex-direction: column;
}
 
.box-bt {
 flex-direction: column-reverse;
}
 
.box-pack-center {
 justify-content: center;
}
.day-week{
 color:#ccc;
 
}
 
.box-pack-start {
 justify-content: flex-start;
}
 
.box-pack-end {
 justify-content: flex-end;
}
 
.box-pack-between {
 justify-content: space-between;
}
 
.box-pack-around {
 justify-content: space-around;
}
 
.box-align-center {
 align-items: center;
}
.years-month{
 color: #000;
}
.box-align-start {
 align-items: flex-start;
}
 
.box-align-end {
 align-items: flex-end;
}
 
.self-align-center {
 align-self: center;
 margin: 0 auto;
}
 
.self-align-start {
 align-self: flex-start;
}
 
.self-align-end {
 align-self: flex-end;
}
 
.self-align-stretch {
 align-self: stretch;
}
 
.box-wrap {
 flex-wrap: wrap;
}
 
.box-nowrap {
 flex-wrap: nowrap;
}
 
.flex {
 flex-grow: 1;
 background: #fff;
}
 
.shrink {
 flex-shrink: 1;
}
.bg {
 background-image: linear-gradient(to bottom, #faefe7, #ffcbd7);
 overflow: hidden;
}
.brown-color {
 color: #784344;
}
.pink-color {
 color: #ff629a;
}
.white-color {
 color: #fff;
}
.fs24 {
 font-size: 24rpx;
}
.fs28 {
 font-size: 28rpx;
}
.fs32 {
 font-size: 32rpx;
}
.fs36 {
 font-size: 36rpx;
}
 
/*灰色显示 */
.grays{
 color: #ccc;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JQuery 应用 JQuery.groupTable.js
Dec 15 Javascript
简短几句jquery代码的实现一个图片向上滚动切换
Sep 02 Javascript
跨浏览器通用、可重用的选项卡tab切换js代码
Sep 20 Javascript
基于JavaScript自定义构造函数的详解说明
Apr 24 Javascript
模拟多级复选框效果的jquery代码
Aug 13 Javascript
JavaScript实现鼠标点击后层展开效果的方法
May 13 Javascript
javascript html5 canvas实现可拖动省份的中国地图
Mar 11 Javascript
js仿3366小游戏选字游戏
Apr 14 Javascript
jQuery 表单序列化实例代码
Jun 11 jQuery
Vue中封装input组件的实例详解
Oct 17 Javascript
详解SPA中前端路由基本原理与实现方式
Sep 12 Javascript
jQuery位置选择器用法实例分析
Jun 28 jQuery
微信小程序自定义带价格显示日历效果
Dec 29 #Javascript
微信小程序日历效果
Dec 29 #Javascript
微信小程序日历组件使用方法详解
Dec 29 #Javascript
微信小程序自定义可滑动日历界面
Dec 28 #Javascript
10行代码实现微信小程序滑动tab切换
Dec 28 #Javascript
微信小程序实现复选框效果
Dec 28 #Javascript
6行代码实现微信小程序页面返回顶部效果
Dec 28 #Javascript
You might like
《PHP边学边教》(02.Apache+PHP环境配置――上篇)
2006/12/13 PHP
用来解析.htpasswd文件的PHP类
2012/09/05 PHP
php利用cookies实现购物车的方法
2014/12/10 PHP
mac系统下为 php 添加 pcntl 扩展
2016/08/28 PHP
php断点续传之文件分割合并详解
2016/12/13 PHP
在Yii2特定页面如何禁用调试工具栏Debug Toolbar详解
2017/08/07 PHP
Web前端设计模式  制作漂亮的弹出层
2010/10/29 Javascript
JavaScript中将一个值转换为字符串的方法分析[译]
2012/09/21 Javascript
jquery 插件开发 extjs中的extend用法小结
2013/01/04 Javascript
如何使用Javascript正则表达式来格式化XML内容
2013/07/04 Javascript
jquery对ajax的支持介绍
2013/12/10 Javascript
JavaScript字符串对象slice方法入门实例(用于字符串截取)
2014/10/16 Javascript
批量下载对路网图片并生成html的实现方法
2016/06/07 Javascript
浅谈js中调用函数时加不加括号的问题
2016/07/28 Javascript
完美实现js焦点轮播效果(二)(图片可滚动)
2017/03/07 Javascript
vuejs实现折叠面板展开收缩动画效果
2018/09/06 Javascript
Vue源码探究之虚拟节点的实现
2019/04/17 Javascript
Postman内建变量常用方法实例解析
2020/07/28 Javascript
vue实现移动端拖动排序
2020/08/21 Javascript
python3 发送任意文件邮件的实例
2018/01/23 Python
Pycharm无法使用已经安装Selenium的解决方法
2018/10/13 Python
详解django+django-celery+celery的整合实战
2019/03/19 Python
基于Python的微信机器人开发 微信登录和获取好友列表实现解析
2019/08/21 Python
在Python IDLE 下调用anaconda中的库教程
2020/03/09 Python
新加坡航空官方网站:Singapore Airlines
2016/10/13 全球购物
River Island美国官网:英国高街时尚品牌
2018/09/04 全球购物
什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?
2016/08/13 面试题
初中美术教学反思
2014/01/29 职场文书
企业演讲比赛主持词
2014/03/18 职场文书
教师求职信范文
2014/05/24 职场文书
大学生作弊检讨书
2014/09/11 职场文书
统计学教授推荐信
2014/09/18 职场文书
教师师德师风自我剖析材料
2014/09/29 职场文书
2015年学校政教处工作总结
2015/05/26 职场文书
创业计划书之健康营养产业
2019/10/15 职场文书
redis连接被拒绝的解决方案
2021/04/12 Redis