<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<style>
table {
display: inline-block;
border: 1px solid red;
/**
HTML5 中 table的cellspacing和cellpadding时被提示该属性已过时或者提示非法属性
border-collapse定义为collapse时,他们的边框会重叠在一起,定义为separate时单元格边框之间会有间隙
*/
border-collapse:collapse;
}
table td {
padding: 0;
width: 2rem;
height: 2rem;
text-align: center;
box-sizing: border-box;
transition: border-radius .5s ease, border-color .5s;
overflow-y: hidden;
}
/* 本来最简单的方法是设置overflow:hidden来遮住多余的背景,但是发现行不通 */
.goPrevMonth>span, .goNextMonth>span {
display: inline-block;
/** 由于原先的箭头太瘪了,需要拉伸 */
transform: scale(1,1.5);
/** 由于箭头是文字,因此会被选中,需要设置禁止选中,不然很难看 */
user-select: none;
-ms-user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
}
.goPrevMonth:active, .goNextMonth:active {
background-color: Bisque;
}
#calendar tr:nth-child(2) {
background-color: SkyBlue;
}
.prevMonth, .nextMonth {
color: gray;
}
.week {
color: Snow;
font-weight: bold;
}
.today {
border-radius: 50%;
color: white;
background-color: Coral;
font-weight: bold;
}
.today:hover {
box-shadow: 0 0 5px red inset , 0 0 3px orange;
border-radius: 0%;
}
.currentMonth {
/** 如果不设置的话,默认的起始色为黑色 */
border-color: transparent;
}
.currentMonth:hover {
border: 2px groove lightgray;
}
</style>
<script>
class CalendarRender {
constructor (container) {
this.container = container;
this.dayOfWeek = ["一","二","三","四","五","六","日"];
this.today = new Date();
//getMonth的月份的参数介于0-11之间
this.firstDayOfMonth = new Date(this.today.getFullYear(), this.today.getMonth(), 1);
this.update(0);
}
//前一个月
goPrevMonth() {
this.update(-1);
}
//后一个月
goNextMonth() {
this.update(1);
}
calc() {
this.data = new Array();
const isCurrentMonth = this.firstDayOfMonth.getMonth() == this.today.getMonth();
const lastDateOfMonth = new Date(this.firstDayOfMonth.getFullYear(), this.firstDayOfMonth.getMonth()+1, 0);
const lastDate = lastDateOfMonth.getDate();
//星期日的值为0
const firstDay = this.firstDayOfMonth.getDay();
let prevCount = 0;
let prevLastDate = 0;
if(firstDay != 1) {
const firstDayOfMonthYesterday = new Date(this.firstDayOfMonth.getFullYear(), this.firstDayOfMonth.getMonth(), 0);
prevLastDate = firstDayOfMonthYesterday.getDate();
if(firstDay == 0) {
prevCount = 6;
} else {
prevCount = firstDay - 1;
}
}
let n = 0;
let m = 0;
for(let i=0; i<5; i++) {
for(let j=0; j<7; j++) {
if(i == 0 && prevCount > j) {
this.data.push([prevLastDate - prevCount + 1 + j, -1]);
} else if(n == lastDate) {
m++;
this.data.push([m,1]);
} else {
n++;
if(isCurrentMonth && n == this.today.getDate()) {
this.data.push([n,0xFF]);
} else {
this.data.push([n,0]);
}
}
}
}
}
render() {
this.container.innerHTML = "";
let index = 0, tr, td;
const table = document.createElement("table");
tr = document.createElement("tr");
const lttd = document.createElement("td");
const gttd = document.createElement("td");
td = document.createElement("td");
//getMonth的月份的参数介于0-11之间
td.textContent = this.firstDayOfMonth.getFullYear() + " 年 " + (this.firstDayOfMonth.getMonth()+1) + " 月"
//colSpan设置列跨度,rowSpan设置行跨度
td.colSpan = 5;
lttd.innerHTML = "<span><</span>";
gttd.innerHTML = "<span>></span>";
lttd.className = "goPrevMonth";
gttd.className = "goNextMonth";
table.appendChild(tr);
tr.appendChild(lttd);
tr.appendChild(td);
tr.appendChild(gttd);
//这么写是错误的,因为click函数中的this不是当前对象,因此可以通过缓存this的办法解决
//lttd.onclick = this.goPrevMonth;
//gttd.onclick = this.goNextMonth;
const that = this;
lttd.onclick=()=>{that.goPrevMonth.apply(that)};
gttd.onclick=()=>{that.goNextMonth.apply(that)};
tr = document.createElement("tr");
for(let i=0; i<this.dayOfWeek.length; i++) {
td = document.createElement("td");
td.innerText = this.dayOfWeek[i];
td.className = "week";
tr.appendChild(td);
}
table.appendChild(tr);
for(let i=0; i<5; i++) {
tr = document.createElement("tr");
for(let j=0; j<7; j++) {
td = document.createElement("td");
const data = this.data[index];
td.textContent = data[0];
index++;
let className;
switch(data[1]) {
case -1:
className = "prevMonth";
break;
case 0:
className = "currentMonth";
break;
case 1:
className = "nextMonth";
break;
case 0xFF:
className = "today";
break;
}
td.className = className;
tr.appendChild(td);
}
table.appendChild(tr);
}
this.container.appendChild(table);
}
update(monthDiff) {
this.firstDayOfMonth.setMonth(this.firstDayOfMonth.getMonth()+monthDiff);
this.calc();
this.render();
}
}
window.()=>{
const calendar = document.getElementById("calendar");
const tool = new CalendarRender(calendar);
}
</script>
</head>
<body>
<div id="calendar"></div>
</body>
</html>
JavaScript 日历
最新推荐文章于 2024-09-14 08:13:53 发布