当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 小程序自定义日历效果

小程序自定义日历效果

2019年01月07日  | 移动技术网IT编程  | 我要评论

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

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

<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;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网