业务需要开发个月日历效果展示,一些独特的功能各种组件都不支持,随自己开发了,使用了纯js,没有用到第三方库,下面是剥离了业务代码的一个demo,虽然写的很垃圾,但还是记录下,如果有用的话,希望能帮到别人,直接上代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>月日历</title>
</head>
<style>
#top {
position: relative;
height: 60px;
text-align: center;
line-height: 60px;
}
table {
background-color: #f7f7f7;
margin: auto;
}
#week td {
font-size: 20px;
font-weight: bold;
}
td {
height: 60px;
width: 60px;
text-align: center;
font-size: 20px;
}
#left, #right {
position: absolute;
width: 60px;
height: 60px;
color: cornflowerblue;
}
#left {
left: 0;
}
#right {
right: 0;
}
#left:hover, #right:hover {
background-color: rgba(30, 30, 30, 0.2);
}
h3{
text-align: center;
}
</style>
<body>
<div>
<h3>示例只做展示,没写样式,需要什么功能自己改改源码就能实现</h3>
<table>
<thead>
<tr>
<td colspan="7">
<div id="top">
<span id="left" class="prev_icon" onclick="preMonth()"><</span>
<span style="font-size: 30px;" id="topInfo"></span>
<span id="right" class="next_icon" onclick="nextMonth()">></span>
</div>
</td>
</tr>
<tr id="week">
<td>日</td>
<td>一</td>
<td>二</td>
<td>三</td>
<td>四</td>
<td>五</td>
<td>六</td>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
</div>
<script src="js/monthlyCalendar.js"></script>
<script type="text/javascript">
init();
</script>
</body>
</html>
/**
* 月历控件v1.0
* @author lks
* @email liangkesai@foxmail.com
*/
/**
* 每月的天数
* @type {number[]}
*/
const monthDay = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
/**
* 顶部显示的年
*/
let topYear;
/**
* 顶部显示的月
*/
let topMonth;
/**
* 初始化
*/
function init() {
let curDate = new Date();
let curYear = curDate.getFullYear();
let curMonth = curDate.getMonth() + 1;
showCld(curYear, curMonth);
}
/**
* 下一月
*/
function nextMonth() {
let year = Number(topYear);
let month = Number(topMonth);
let nextMonth = month + 1;
if (nextMonth > 12) {
nextMonth = 1;
year++;
}
showCld(year, nextMonth);
}
/**
* 上一月
*/
function preMonth() {
let year = Number(topYear);
let month = Number(topMonth);
let preMonth = month - 1;
if (preMonth < 1) {
preMonth = 12;
year--;
}
showCld(year, preMonth);
}
/**
* 显示日历
* @param year
* @param month
*/
function showCld(year, month) {
let firstDay = whatDay(year, month);
topYear = year;
topMonth = month;
//值写入顶部
document.getElementById("topInfo").innerText = topYear+"年"+topMonth+"月";
let curDate = new Date();
//从数组里取出该月的天数
let days;
if (month === 2) {
if (isLeap(year)) {
days = 29;
} else {
days = 28;
}
} else {
days = monthDay[month - 1];
}
//添加日期部分
let tbodyHtml = '<tr>';
//对1号前空白格的填充
for (let i = 0; i < firstDay; i++) {
tbodyHtml += "<td></td>";
}
let changLine = firstDay;
//每一个日期的填充
for (let i = 1; i <= days; i++) {
if (year === curDate.getFullYear() && month === curDate.getMonth() + 1 && i === curDate.getDate()) {
//当前日期对应格子
tbodyHtml += "<td style='color: red'><label>" + i + "</label></td>";
} else {
//普通日期对应格子
tbodyHtml += "<td><label>" + i + "</label></td>";
}
changLine = (changLine + 1) % 7;
if (changLine === 0 && i !== days) {
//是否换行填充的判断
tbodyHtml += "</tr><tr>";
}
}
//添加结束,对该行剩余位置的空白填充
if (changLine !== 0) {
for (let i = changLine; i < 7; i++) {
tbodyHtml += "<td></td>";
}
}
tbodyHtml += "</tr>";
let tbody = document.getElementById('tbody');
tbody.innerHTML = tbodyHtml;
}
/**
* 判断某年某月某日是星期几
* @param year
* @param month
* @param day
* @returns {number} 余数为0代表那天是周日,为1代表是周一,以此类推
*/
function whatDay(year, month, day = 1) {
let sum = 0;
sum += (year - 1) * 365 + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) + Math.floor((year - 1) / 400) + day;
for (let i = 0; i < month - 1; i++) {
sum += monthDay[i];
}
if (month > 2) {
if (isLeap(year)) {
sum += 29;
} else {
sum += 28;
}
}
//余数为0代表那天是周日,为1代表是周一,以此类推
return sum % 7;
}
/**
* 是否是闰年
* @param year
* @returns {boolean}
*/
function isLeap(year) {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
}