JavaScript 日历

在这里插入图片描述

<!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>&lt</span>";
		gttd.innerHTML = "<span>&gt</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>
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"> //创建一个数组,用于存放每个月的天数 function montharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11)  { this[0] = m0; this[1] = m1; this[2] = m2; this[3] = m3; this[4] = m4; this[5] = m5; this[6] = m6; this[7] = m7; this[8] = m8; this[9] = m9; this[10] = m10; this[11] = m11; } //实现月历 function calendar() { var monthNames = "JanFebMarAprMayJunJulAugSepOctNovDec"; var today = new Date(); var thisDay; var monthDays = new montharr(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); year = today.getYear() +1900; thisDay = today.getDate(); if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) monthDays[1] = 29; nDays = monthDays[today.getMonth()]; firstDay = today; firstDay.setDate(1); testMe = firstDay.getDate(); if (testMe == 2) firstDay.setDate(0); startDay = firstDay.getDay(); document.write("<div id='rili' style='position:absolute;width:140px;left:300px;top:100px;'>")  document.write("<TABLE width='217' BORDER='0' CELLSPACING='0' CELLPADDING='2' BGCOLOR='#0080FF'>") document.write("<TR><TD><table border='0' cellspacing='1' cellpadding='2' bgcolor='Silver'>"); document.write("<TR><th colspan='7' bgcolor='#C8E3FF'>"); var dayNames = new Array("星期日","星期一","星期二","星期三","星期四","星期五","星期六"); var monthNames = new Array("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"); var now = new Date(); document.writeln("<FONT STYLE='font-size:9pt;Color:#330099'>" + "公元 " + now.getYear() + "年" + monthNames[now.getMonth()] + " " + now.getDate() + "日 " + dayNames[now.getDay()] + "</FONT>"); document.writeln("</TH></TR><TR><TH BGCOLOR='#0080FF'><FONT STYLE='font-size:9pt;Color:White'>日</FONT></TH>"); document.writeln("<th bgcolor='#0080FF'><FONT STYLE='font-size:9pt;Color:White'>一</FONT></TH>"); document.writeln("<TH BGCOLOR='#0080FF'><FONT STYLE='font-size:9pt;Color:White'>二</FONT></TH>"); document.writeln("<TH BGCOLOR='#0080FF'><FONT STYLE='font-size:9pt;Color:White'>三</FONT></TH>"); document.writeln("<TH BGCOLOR='#0080FF'><FONT STYLE='font-size:9pt;Color:White'>四</FONT></TH>"); document.writeln("<TH BGCOLOR='#0080FF'><FONT STYLE='font-size:9pt;Color:White'>五</FONT></TH>"); document.writeln("<TH BGCOLOR='#0080FF'><FONT STYLE='font-size:9pt;Color:White'>六</FONT></TH>"); document.writeln("</TR><TR>"); column = 0; for (i=0; i<startDay; i++) { document.writeln("\n<TD><FONT STYLE='font-size:9pt'> </FONT></TD>"); column++; } for (i=1; i<=nDays; i++) { if (i == thisDay) { document.writeln("</TD><TD ALIGN='CENTER' BGCOLOR='#FF8040'><FONT STYLE='font-size:9pt;Color:#ffffff'><B>") } else { document.writeln("</TD><TD BGCOLOR='#FFFFFF' ALIGN='CENTER'><FONT STYLE='font-size:9pt;font-family:Arial;font-weight:bold;Color:#330066'>"); } document.writeln(i); if (i == thisDay) document.writeln("</FONT></TD>") column++; if (column == 7) { document.writeln("<TR>");  column = 0; } } document.writeln("<TR><TD COLSPAN='7' ALIGN='CENTER' VALIGN='TOP' BGCOLOR='#0080FF'>") document.writeln("<FORM NAME='clock' onSubmit='0'><FONT STYLE='font-size:9pt;Color:#ffffff'>") document.writeln(" 现在时间:<INPUT TYPE='Text' NAME='face' ALIGN='TOP'></FONT></FORM></TD></TR></TABLE>") document.writeln("</TD></TR></TABLE></div>"); } </SCRIPT>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值