### HTML+TypeScript实现自定义样式日历

本文介绍如何使用HTML、TypeScript及Ionic框架实现一个带有自定义样式的日历组件。该组件可以根据不同日期设置不同的样式,并支持前后月份切换。

最近在用ionic框架开发一个移动应用的项目,给了个需求给我,要实现一个日历,并能够给每个日期自定义样式,看了一下他用的组件,发现改不了,在网上找了一圈,也没发现比较满意的,那就自己动手,丰衣足食。将代码记录下来,以便以后工作中能用上。用html+typescript实现一个日历,下面直接贴代码

页面
<div id="calendar">
    <div class="head">
      <ion-icon name="ios-arrow-back" (click)="selectLastMon()"></ion-icon>
      <span>{{selectDay.year}}年{{selectDay.month}}月</span>
      <ion-icon name="ios-arrow-forward" (click)="selectNextMon()"></ion-icon>
    </div>
    <div class="body">
      <span *ngFor="let item of weekdays">{{item}}</span>
    </div>
    <div class="days">
      <span *ngFor="let item of days" (click)="selectDate(item)" class="{{item.status}}">{{item.date}}</span>
    </div>
  </div>
复制代码
scss样式
#calendar {
    span {
      line-height: 4.5rem;
      text-align: center;
    }
    .head {
      background-color: #15ACEB;
      display: flex;
      .icon-md {
        flex: 1;
        text-align: center;
        font-size: 3rem;
        line-height: 4.5rem;
        color: white;
      }
      span {
        flex: 2;
        font-size: 2rem;
        color: white;
      }
    }
    .body {
      display: flex;
      span {
        flex: 1;
        font-size: 1.6rem;
        color: black;
        background-color: white;
      }
    }
    .days {
      span {
        width: 14.28%;
        float: left;
        font-size: 1.6rem;
        color: black;
        background-color: white;
      }
      //日历显示中每个日期所对应的样式,可以自己定义
      .s {
        background-color: #15ACEB;
        color: white;
      }
      .o {
        color: #aaaaaa;
      }
      .t {
        color: #666666;
      }
      .y {
        color: #f7e023;
      }
    }
  }
复制代码

TypeScript文件

    //首先通过new Date()获取当前时间并将年月日处理后赋值给selectDay,然后传入initCalendar()方法初始化日历
    initCalendar(selectDay) {
        //获取选中日期所在月份天数
        let days = new Date(selectDay.year, selectDay.month, 0).getDate();
        //获取选中日期所在月份1号是星期几,星期几就返回几
        let weekday = new Date(selectDay.year + ', ' + selectDay.month + ', 01').getDay();
        weekday = weekday == 0? 7: weekday;
        this.initLastMon(selectDay, weekday);
        this.initThisMon(selectDay, days);
        this.initNextMon(selectDay, weekday + days);
    }
    //初始化显示出来的上月天数
    initLastMon(selectDay, weekday){
        let i = 1;
        while(i <= weekday) {
         //如果本月为1月则上月为上一年的12月,根据星期判断显示的上月天数
          if(selectDay.month == '01') {
            let date = (31 - weekday) + i;
            this.days.push({year: selectDay.year - 1,month: 12,date: date,status: 'o'});
          }else {
          //如果不是1月则先得到上月天数,从显示的第一天开始依次往数组里面放入日期对象,样式为'o'
            let lastMonDays = new Date(selectDay.year,parseInt(selectDay.month) - 1,0).getDate();
            let month = 10 > (parseInt(selectDay.month) - 1)? '0' + (parseInt(selectDay.month) - 1): (parseInt(selectDay.month) - 1) + '';
            let date = (lastMonDays - weekday) + i;
            this.days.push({year: selectDay.year, month: month, date: date, status: 'o'});
          }
          i += 1;
        }
    }
    //初始化本月显示日期
    initThisMon(selectDay, days) {
        //接着依次从第一天将本月所有天数都放进数组
        for(let i = 1; i <= days; i++){
          let year = selectDay.year;
          let month = selectDay.month;
          let date = 10 > i? '0' + i: i + '';
          //在这里控制自己想要显示的本月日期的样式
          //若是选中的那天,则样式为's'
          if(i == parseInt(selectDay.date)){
            this.days.push({year: year, month: month, date: date, status:'s'});
          }else{
            this.days.push({year: year, month: month, date: date, status:'t'});
          }
        }
    }
    //初始化下月显示日期
    initNextMon(selectDay, days){
        let i = 1;
        //放入42-(上月显示天数+本月天数)天
        while((i + days) <= 42){
          let date = 10 > i? '0' + i: i + '';
          //如果本月是12月,下月为下一年1月,从1号开始显示
          if(selectDay.month == '12') {
            this.days.push({year: selectDay.year + 1, month: '01', date: date, status: 'o'});
          }else {
            let month = 10 > (parseInt(selectDay.month) + 1)? '0' + (parseInt(selectDay.month) + 1): (parseInt(selectDay.month) + 1) + '';
            this.days.push({year: selectDay.year, month: month, date: date, status: 'o'});
          }
          i += 1;
        }
    }
    //选中日期触发事件
    selectDate(item) {
        //如果选中的日期为本月的日期
        if(item.month == this.selectDay.month) {
        //获取之前被选中的日期在数组中的下标,修改样式为't'
          let index = new Date(this.selectDay.year + ', ' + this.selectDay.month + ', 01').getDay() + parseInt(this.selectDay.date) - 1;
          this.days[index].status = 't';
          //将选中日期的样式修改为's'
          item.status = 's';
          //将被选中日期修改为本次选中日期对象
          this.selectDay = item;
        }else {
          //若选中日期不为本月日期,则将被选中日期修改为本次选中日期对象,清空数组重新初始化日历数组
          this.selectDay = item;
          this.days = [];
          this.initCalendar(item);
        }
    }
    //点击下一月触发事件
    selectNextMon() {
        //若目前被选中日期为12月,则将被选中日期改为下一年1月当日
        if(this.selectDay.month == '12') {
          this.selectDay.year += 1;
          this.selectDay.month = '01';
        }else {
          //若当前不为12月,则将月份+1,然后判断下一月天数与当前被选中日期的大小
          let month = 10 > (parseInt(this.selectDay.month) + 1)? '0'+(parseInt(this.selectDay.month) + 1): (parseInt(this.selectDay.month) + 1) + '';
          let days = new Date(this.selectDay.year,parseInt(month),0).getDate();
          //若下一月天数小于当前被选中日期,则将日期改为下月最后一天
          if(this.selectDay.date > days) {
            this.selectDay.date = days;
          }
          this.selectDay.month = month;
        }
        //清空数组重新初始化日历数组
        this.days = [];
        this.initCalendar(this.selectDay);
    }
    //点击上一月触发事件
    selectLastMon() {
      //若目前被选中日期为1月,则将被选中日期改为上一年12月当日
      if(this.selectDay.month == '01') {
        this.selectDay.year -= 1;
        this.selectDay.month = '12';
      }else {
        //若当前不为1月,则将月份-1,然后判断上一月天数与当前被选中日期的大小
        let month = 10 > (parseInt(this.selectDay.month) - 1)? '0' + (parseInt(this.selectDay.month) - 1): (parseInt(this.selectDay.month) - 1) + '';
        let days = new Date(this.selectDay.year, parseInt(month), 0).getDate();
        //若上一月天数小于当前被选中日期,则将日期改为上月最后一天
        if(this.selectDay.date > days) {
          this.selectDay.date = days;
        }
        this.selectDay.month = month;
      }
      //清空数组重新初始化日历数组
      this.days = [];
      this.initCalendar(this.selectDay);
    }
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值