小程序自定义日历效果


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 相关文章推荐
根据分辨率不同,调用不同的css文件
Jul 07 Javascript
String.prototype实现的一些javascript函数介绍
Nov 22 Javascript
页面元素绑定jquery toggle后元素隐藏的解决方法
Mar 27 Javascript
javascript如何使用bind指定接收者
May 04 Javascript
javascript操作excel生成报表示例
May 08 Javascript
jQuery插件dataTables添加序号列的方法
Jul 06 Javascript
javascript cookie基础应用之记录用户名的方法
Sep 20 Javascript
详解JS中遍历语法的比较
Apr 07 Javascript
jQuery.Ajax()的data参数类型详解
Jul 23 jQuery
angular6.0开发教程之如何安装angular6.0框架
Jun 29 Javascript
微信小程序纯文本实现@功能
Apr 08 Javascript
antd的select下拉框因为数据量太大造成卡顿的解决方式
Oct 31 Javascript
微信小程序自定义带价格显示日历效果
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下使用无限生命期Session的方法
2007/03/16 PHP
php简单获取目录列表的方法
2015/03/24 PHP
Yii2.0框架behaviors方法使用实例分析
2019/09/30 PHP
解决Laravel无法使用COOKIE和SESSION的问题
2019/10/16 PHP
PhpStorm连接服务器并实现自动上传功能
2020/12/09 PHP
ExtJS 入门
2010/10/29 Javascript
JS控件的生命周期介绍
2012/10/22 Javascript
JavaScript mapreduce工作原理简析
2012/11/25 Javascript
jquery选择器原理介绍($()使用方法)
2014/03/25 Javascript
基于javascript实现判断移动终端浏览器版本信息
2014/12/09 Javascript
原生js实现新闻列表展开/收起全文功能
2017/01/20 Javascript
jQuery EasyUI ProgressBar进度条组件
2017/02/28 Javascript
jQuery实现的背景颜色渐变动画效果示例
2017/03/24 jQuery
微信小程序新增的拖动组件movable-view使用教程
2017/05/20 Javascript
webpack2.0配置postcss-loader的方法
2017/08/17 Javascript
解决微信二次分享不显示摘要和图片的问题
2017/08/18 Javascript
Vee-Validate的使用方法详解
2017/09/22 Javascript
js中bool值的转换及“&amp;&amp;”、“||”、 “!!”详解
2017/12/21 Javascript
VUE项目初建和常见问题总结
2019/09/12 Javascript
Python 编码Basic Auth使用方法简单实例
2017/05/25 Python
python3使用pyqt5制作一个超简单浏览器的实例
2017/10/19 Python
python对XML文件的操作实现代码
2020/03/27 Python
CSS3中currentColor关键字的妙用
2016/02/27 HTML / CSS
Canvas实现放大镜效果完整案例分析(附代码)
2020/11/26 HTML / CSS
新加坡时尚网上购物:Zalora新加坡
2016/07/26 全球购物
新闻专业大学生找工作的自我评价
2013/10/30 职场文书
人力资源经理自我评价
2014/01/04 职场文书
违反工作纪律检讨书
2014/02/15 职场文书
写求职信要注意什么问题
2014/04/12 职场文书
英语演讲稿3分钟
2014/04/29 职场文书
开展党的群众路线教育实践活动剖析材料
2014/10/13 职场文书
群众路线自我剖析及整改措施
2014/11/04 职场文书
2015年社区环境卫生工作总结
2015/04/21 职场文书
交通事故赔偿起诉书
2015/05/20 职场文书
小学四年级作文之最感动的一件事
2019/11/01 职场文书
Node.js实现爬取网站图片的示例代码
2022/04/04 NodeJs