纯JS代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Calendar</title>
<style>
.calendar-container {
padding: 30px;
width: 576px;
}
.date-container {
text-align: center;
height: 50px;
line-height: 50px;
}
/*上一月下一月按钮*/
#preMonth,#nextMonth {
position: relative;
}
#preMonth:after {
content: '<';
position: absolute;
left: -28px;
top: -1px;
width: 24px;
text-align: center;
line-height: 24px;
border-radius: 21px;
background-color:brown;
color: white;
}
#nextMonth:after {
content: '>';
position: absolute;
left: 4px;
top: -1px;
width: 24px;
text-align: center;
line-height: 24px;
border-radius: 21px;
background-color:brown;
color: white;
}
#nowYear,#nowMonth,#nowDate{
padding: 0 5px;
}
.week-item {
display: inline-block;
width: 80px;
height: 60px;
line-height: 60px;
border: 1px solid #EEEEEE;
text-align: center;
}
.date-item {
display: inline-block;
width: 80px;
line-height: 80px;
border: 1px solid #EEEEEE;
text-align: center;
}
</style>
</head>
<body>
<div class="calendar-container">
<div class="date-container">
<span id="preMonth" class="year-prev"></span>
<span id="nowYear" class="year-now"></span>
<span id="nowMonth"></span>
<span id="nowDate"></span>
<span id="nextMonth" class="year-next"></span>
</div>
<div id="weekLine" class="week-line"></div>
<div id="dateWrap" class="date-wrap"></div>
</div>
</body>
</html>
<script>
// 1.为了获得每个月的日期有多少,我们需要判断 平年闰年[四年一闰,百年不闰,四百年再闰]
const isLeapYear = (year) => {
return (year % 400 === 0) || (year % 100 !== 0 && year % 4 === 0);
};
// 2.获得每个月的日期有多少,注意 month - [0-11]
const getMonthCount = (year, month) => {
let arr = [
31, null, 31, 30,
31, 30, 31, 31,
30, 31, 30, 31
];
let count = arr[month] || (isLeapYear(year) ? 29 : 28);
return Array.from(new Array(count), (item, value) => value + 1);
};
// 3.获得某年某月的 1号 是星期几,这里要注意的是 JS 的 API-getDay() 是从 [日-六](0-6),返回 number
const getWeekday = (year, month) => {
let date = new Date(year, month, 1);
return date.getDay();
};
// 4.获得上个月的天数
const getPreMonthCount = (year, month) => {
if (month === 0) {
return getMonthCount(year - 1, 11);
} else {
return getMonthCount(year, month - 1);
}
};
// 5.获得下个月的天数
const getNextMonthCount = (year, month) => {
if (month === 11) {
return getMonthCount(year + 1, 0);
} else {
return getMonthCount(year, month + 1);
}
};
// 工具方法 - end
let weekStr = '日一二三四五六';
weekArr = weekStr.split('').map(item => '星期' + item);
// 插入星期 dom
let weekDomStr = '';
let oFragWeek = document.createDocumentFragment();
weekArr.forEach(item => {
let oSpan = document.createElement('span');
let oText = document.createTextNode(item);
oSpan.appendChild(oText);
oSpan.classList.add('week-item');
oFragWeek.appendChild(oSpan);
});
let weekWrap = document.getElementById('weekLine');
weekWrap.appendChild(oFragWeek);
// 这里获得第一次的 数据 数组
const updateCalendar = (year, month, day) => {
if (typeof year === 'undefined' && typeof month === 'undefined' && typeof day === 'undefined') {
let nowDate = new Date();
year = nowDate.getFullYear();
month = nowDate.getMonth();
day = nowDate.getDate();
}
// 更新一下顶部的年月显示
document.getElementById('nowYear').innerHTML = year;
document.getElementById('nowMonth').innerHTML = month + 1;
document.getElementById('nowDate').innerHTML = day;
// 生成日历数据,上个月剩下的的 x 天 + 当月的 28(平年的2月)或者29(闰年的2月)或者30或者31天 + 下个月的 y 天 = 42
let res = [];
let currentMonth = getMonthCount(year, month);
let preMonth = getPreMonthCount(year, month);
let nextMonth = getNextMonthCount(year, month);
let whereMonday = getWeekday(year, month);
if (whereMonday === 0) {
whereMonday = 7
}
// 这里当 whereMonday 为 0 的时候会截取上月的所有数据
let preArr = preMonth.slice(-1 * whereMonday)
let nextArr = nextMonth.slice(0, 42 - currentMonth.length - whereMonday);
res = [].concat(preArr, currentMonth, nextArr);
// 更新 dom 的信息的问题
let hadDom = document.getElementsByClassName('date-item');
if (hadDom && hadDom.length) {
let domArr = document.getElementsByClassName('date-item');
for (let i = 0; i < domArr.length; i++) {
domArr[i].innerHTML = res.shift();
}
} else {
// 如果之前没有结构的话
let str = '';
for (let i = 0; i < 5; i++) {
str += '<div class="date-line">';
for (let j = 0; j < 7; j++) {
str += `<span class='date-item'>${res.shift()}</span>`;
if (j === 6) {
str += '</div>';
}
}
}
document.getElementById('dateWrap').innerHTML = str;
}
};
updateCalendar();
// 添加上一月,下一月事件
let oPreButton = document.getElementById('preMonth');
let oNextButton = document.getElementById('nextMonth');
oPreButton.addEventListener('click', function () {
let currentYear = +document.getElementById('nowYear').textContent;
let currentMonth = +document.getElementById('nowMonth').textContent - 1;
let currentDate = +document.getElementById('nowDate').textContent;
if (currentMonth === 0) {
updateCalendar(currentYear - 1, 11, currentDate);
} else {
updateCalendar(currentYear, currentMonth - 1, currentDate);
}
});
oNextButton.addEventListener('click', function () {
let currentYear = +document.getElementById('nowYear').textContent;
let currentMonth = +document.getElementById('nowMonth').textContent - 1;
let currentDate = +document.getElementById('nowDate').textContent;
if (currentMonth === 11) {
updateCalendar(currentYear + 1, 0, currentDate);
} else {
updateCalendar(currentYear, currentMonth + 1, currentDate);
}
});
</script>
使用了Jquery
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Calendar</title>
<style>
.calendar-container {
padding: 30px;
width: 576px;
}
.date-container {
text-align: center;
height: 50px;
line-height: 50px;
}
/*上一月下一月按钮*/
#preMonth,#nextMonth {
position: relative;
}
#preMonth:after {
content: '<';
position: absolute;
left: -28px;
top: -1px;
width: 24px;
text-align: center;
line-height: 24px;
border-radius: 21px;
background-color:brown;
color: white;
}
#nextMonth:after {
content: '>';
position: absolute;
left: 4px;
top: -1px;
width: 24px;
text-align: center;
line-height: 24px;
border-radius: 21px;
background-color:brown;
color: white;
}
#nowYear,#nowMonth,#nowDate{
padding: 0 5px;
}
.week-item {
display: inline-block;
width: 80px;
height: 60px;
line-height: 60px;
border: 1px solid #EEEEEE;
text-align: center;
}
.date-item {
display: inline-block;
width: 80px;
line-height: 80px;
border: 1px solid #EEEEEE;
text-align: center;
}
</style>
</head>
<body>
<div class="calendar-container">
<div class="date-container">
<span id="preMonth" class="year-prev"></span>
<span id="nowYear" class="year-now"></span>
<span id="nowMonth"></span>
<span id="nowDate"></span>
<span id="nextMonth" class="year-next"></span>
</div>
<div id="weekLine" class="week-line"></div>
<div id="dateWrap" class="date-wrap"></div>
</div>
</body>
</html>
<!--JQuery-->
<script src="https://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
<script>
/**
* 1.判断平年闰年[四年一闰,百年不闰,四百年再闰]
*/
function isLeapYear(year) {
return (year % 400 === 0) || (year % 100 !== 0 && year % 4 === 0);
}
/**
* 2.获得每个月有几天,注意 month是[0-11]
*/
function getMonthCount(year, month) {
let arr = [
31, null, 31, 30,
31, 30, 31, 31,
30, 31, 30, 31
];
let count = arr[month] || (isLeapYear(year) ? 29 : 28);
return Array.from(new Array(count), (item, value) => value + 1);
}
/**
* 3.获得某年某月的 1号 是星期几,这里要注意的是 JS 的 API-getDay() 是从 [日-六](0-6),返回 number
*/
function getWeekday(year, month) {
let date = new Date(year, month, 1);
return date.getDay();
}
/**
* 4.获得上个月的天数
*/
function getPreMonthCount(year, month) {
if (month === 0) {
return getMonthCount(year - 1, 11);
} else {
return getMonthCount(year, month - 1);
}
}
/**
* 5.获得下个月的天数
*/
function getNextMonthCount(year, month) {
if (month === 11) {
return getMonthCount(year + 1, 0);
} else {
return getMonthCount(year, month + 1);
}
}
// 工具方法 - end
let weekStr = '日一二三四五六';
weekArr = weekStr.split('').map(item => '星期' + item);
// 插入星期 dom
let weekDomStr = '';
let oFragWeek = document.createDocumentFragment();
weekArr.forEach(item => {
let oSpan = document.createElement('span');
let oText = document.createTextNode(item);
oSpan.appendChild(oText);
oSpan.classList.add('week-item');
oFragWeek.appendChild(oSpan);
});
let weekWrap = document.getElementById('weekLine');
weekWrap.appendChild(oFragWeek);
// 这里获得第一次的 数据 数组
const updateCalendar = (year, month, day) => {
if (typeof year === 'undefined' && typeof month === 'undefined' && typeof day === 'undefined') {
let nowDate = new Date();
year = nowDate.getFullYear();
month = nowDate.getMonth();
day = nowDate.getDate();
}
// 更新一下顶部的年月显示
document.getElementById('nowYear').innerHTML = year;
document.getElementById('nowMonth').innerHTML = month + 1;
document.getElementById('nowDate').innerHTML = day;
// 生成日历数据,上个月剩下的的 x 天 + 当月的 28(平年的2月)或者29(闰年的2月)或者30或者31天 + 下个月的 y 天 = 42
let res = [];
let currentMonth = getMonthCount(year, month);
let preMonth = getPreMonthCount(year, month);
let nextMonth = getNextMonthCount(year, month);
let whereMonday = getWeekday(year, month);
if (whereMonday === 0) {
whereMonday = 7
}
// 这里当 whereMonday 为 0 的时候会截取上月的所有数据
let preArr = preMonth.slice(-1 * whereMonday)
let nextArr = nextMonth.slice(0, 42 - currentMonth.length - whereMonday);
res = [].concat(preArr, currentMonth, nextArr);
// 更新 dom 的信息的问题
let hadDom = document.getElementsByClassName('date-item');
if (hadDom && hadDom.length) {
let domArr = document.getElementsByClassName('date-item');
for (let i = 0; i < domArr.length; i++) {
domArr[i].innerHTML = res.shift();
}
} else {
// 如果之前没有结构的话
let str = '';
for (let i = 0; i < 5; i++) {
str += '<div class="date-line">';
for (let j = 0; j < 7; j++) {
str += `<span class='date-item'>${res.shift()}</span>`;
if (j === 6) {
str += '</div>';
}
}
}
document.getElementById('dateWrap').innerHTML = str;
}
};
updateCalendar();
// 点击上一月
$('#preMonth').click(function () {
let currentYear = $('#nowYear').html(); //年
let currentMonth = $('#nowMonth').html() - 1; //月
let currentDate = document.getElementById('nowDate').textContent;
if (currentMonth === 0) {
updateCalendar(currentYear - 1, 11, currentDate);
} else {
updateCalendar(currentYear, currentMonth - 1, currentDate);
}
});
// 点击下一月
$('#nextMonth').click(function () {
let currentYear = document.getElementById('nowYear').textContent;
let currentMonth = document.getElementById('nowMonth').textContent - 1;
let currentDate = document.getElementById('nowDate').textContent;
if (currentMonth === 11) {
updateCalendar(currentYear + 1, 0, currentDate);
} else {
updateCalendar(currentYear, currentMonth + 1, currentDate);
}
});
</script>