最近在用
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);
}
复制代码