需求:显示6行7列的日历表 (日期部分)
分析:
1.确定某年某月的日历
2.分成三部分
- 1.当前月份所有日期 1号到最后一号
- 2.前一月部分
- 3.后一月部分
3. 确定当前月最后一天
比如 获得2025年11月最后一天(也就是11月有几天)
ts
lastdate = new Date(2025,11,0)
curMonthLastDay = lastdate.getDate() //30
4.获取上一月最后一天
比如 获得2025年10月最后一天(也就是10月有几天)
ts
lastdate = new Date(2025,10,0)
preMonthLastDay = lastdate.getDate() //31
5.补充上一月部分
- 1.确定当前月第一天 为周几
比如 获得2025年11月第一天为周几
ts
firstdate = new Date(2025,10,1)
firstdate.getDay() //6
//注意: 0代表周日
-
2.根据日历 星期是从周日开始还是周一开始确定需要补充上一月的几天
-
- 1.周日开始
daysFromPreMonth = firstdat.getDay()
- 1.周日开始
-
- 2.周一开始
daysFromPreMonth = (firstdate.getDay() + 6) % 7
- 2.周一开始
-
3.补充上一月部分
ts
let calendarDays=[];
for (let i = daysFromPreMonth - 1, i >= 0 ; i-- ){
calendarDays.push({ date: preMonthLastDay - i; isCurrentMonth : false;})}
5.添加本月部分
ts
for (let i = 1, i <= curMonthLastDay ; i++ ){
calendarDays.push(
{
date: i;
isCurrentMonth : true;
})
}
6.添加下个月的日期
ts
const restDays = 42 - calendarDays.length
for (let i = 1, i <= restDays ; i++ ){
calendarDays.push(
{
date: i;
isCurrentMonth : false;
})
}
7.实际代码
ts
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>双视图日历对比</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
padding: 20px;
}
.calendar-comparison {
display: flex;
gap: 30px;
max-width: 900px;
width: 100%;
flex-wrap: wrap;
justify-content: center;
}
.calendar-container {
background-color: white;
border-radius: 12px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1);
padding: 20px;
width: 100%;
max-width: 420px;
transition: transform 0.3s ease;
}
.calendar-container:hover {
transform: translateY(-5px);
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #eaeaea;
}
.calendar-header h2 {
margin: 0;
color: #2c3e50;
font-size: 1.4rem;
}
.nav-button {
background-color: #3498db;
color: white;
border: none;
border-radius: 50%;
width: 36px;
height: 36px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
transition: background-color 0.2s;
}
.nav-button:hover {
background-color: #2980b9;
}
.calendar-table {
width: 100%;
border-collapse: collapse;
}
.calendar-table th {
background-color: #f8f9fa;
padding: 12px 5px;
text-align: center;
font-weight: 600;
color: #34495e;
border: 1px solid #eaeaea;
}
.calendar-table td {
border: 1px solid #eaeaea;
padding: 12px 5px;
text-align: center;
height: 40px;
vertical-align: middle;
transition: all 0.2s;
position: relative;
}
.current-month {
background-color: white;
color: #2c3e50;
}
.other-month {
background-color: #f8f9fa;
color: #bdc3c7;
}
.today {
background-color: #e1f0fa;
color: #2980b9;
font-weight: bold;
border: 1px solid #3498db;
}
.calendar-title {
text-align: center;
margin-bottom: 10px;
color: #7f8c8d;
font-size: 0.9rem;
font-weight: 500;
}
@media (max-width: 768px) {
.calendar-comparison {
flex-direction: column;
align-items: center;
}
.calendar-container {
max-width: 100%;
}
}
</style>
</head>
<body>
<div class="calendar-comparison">
<div class="calendar-container">
<div class="calendar-title">周日开始的日历(传统)</div>
<div class="calendar-header">
<button class="nav-button" id="prevMonthLeft">←</button>
<h2 id="monthYearLeft">2025年十一月</h2>
<button class="nav-button" id="nextMonthLeft">→</button>
</div>
<table class="calendar-table">
<thead>
<tr>
<th>日</th>
<th>一</th>
<th>二</th>
<th>三</th>
<th>四</th>
<th>五</th>
<th>六</th>
</tr>
</thead>
<tbody id="calendarBodyLeft">
<!-- 左侧日历内容将通过JavaScript动态生成 -->
</tbody>
</table>
</div>
<div class="calendar-container">
<div class="calendar-title">周一开始的日历(国际标准)</div>
<div class="calendar-header">
<button class="nav-button" id="prevMonthRight">←</button>
<h2 id="monthYearRight">2025年十一月</h2>
<button class="nav-button" id="nextMonthRight">→</button>
</div>
<table class="calendar-table">
<thead>
<tr>
<th>一</th>
<th>二</th>
<th>三</th>
<th>四</th>
<th>五</th>
<th>六</th>
<th>日</th>
</tr>
</thead>
<tbody id="calendarBodyRight">
<!-- 右侧日历内容将通过JavaScript动态生成 -->
</tbody>
</table>
</div>
</div>
<script>
// 当前显示的年份和月份
let currentYear = new Date().getFullYear();
let currentMonth = new Date().getMonth();
// 月份名称数组
const monthNames = ["一月", "二月", "三月", "四月", "五月", "六月",
"七月", "八月", "九月", "十月", "十一月", "十二月"];
// 初始化日历
document.addEventListener('DOMContentLoaded', function () {
updateCalendars();
// 为所有导航按钮添加事件监听器
document.getElementById('prevMonthLeft').addEventListener('click', goToPreviousMonth);
document.getElementById('nextMonthLeft').addEventListener('click', goToNextMonth);
document.getElementById('prevMonthRight').addEventListener('click', goToPreviousMonth);
document.getElementById('nextMonthRight').addEventListener('click', goToNextMonth);
});
// 切换到上一个月
function goToPreviousMonth() {
currentMonth--;
if (currentMonth < 0) {
currentMonth = 11;
currentYear--;
}
updateCalendars();
}
// 切换到下一个月
function goToNextMonth() {
currentMonth++;
if (currentMonth > 11) {
currentMonth = 0;
currentYear++;
}
updateCalendars();
}
// 更新两个日历
function updateCalendars() {
generateCalendar('calendarBodyLeft', 'sunday', 'monthYearLeft');
generateCalendar('calendarBodyRight', 'monday', 'monthYearRight');
}
// 生成日历的主要函数
function generateCalendar(targetBodyId, startOfWeek, monthYearId) {
// 更新月份和年份显示
document.getElementById(monthYearId).textContent = `${currentYear}年 ${monthNames[currentMonth]}`;
// 获取当前月的第一天
const firstDay = new Date(currentYear, currentMonth, 1);
// 获取当前月最后一天(即当前月的天数)
const curMonthLastDay = new Date(currentYear, currentMonth + 1, 0).getDate();
// 获取上一月最后一天(即上一月的天数)
const prevMonthLastDay = new Date(currentYear, currentMonth, 0).getDate();
// 获取当前月第一天是星期几(0代表周日,6代表周六)
const firstDayOfWeek = firstDay.getDay();
// 计算需要从上一月补充的天数
let daysFromPrevMonth;
if (startOfWeek === 'sunday') {
// 周日开始的日历
daysFromPrevMonth = firstDayOfWeek;
} else {
// 周一开始的日历
daysFromPrevMonth = (firstDayOfWeek + 6) % 7;
}
// 创建日历数组
const calendarDays = [];
// 添加上一月的日期
for (let i = daysFromPrevMonth - 1; i >= 0; i--) {
calendarDays.push({
date: prevMonthLastDay - i,
isCurrentMonth: false
});
}
// 添加当前月的日期
for (let i = 1; i <= curMonthLastDay; i++) {
calendarDays.push({
date: i,
isCurrentMonth: true
});
}
// 计算并添加下一月的日期,使日历总天数为42天(6行×7列)
const totalCells = 42;
const remainingDays = totalCells - calendarDays.length;
for (let i = 1; i <= remainingDays; i++) {
calendarDays.push({
date: i,
isCurrentMonth: false
});
}
// 获取今天日期,用于高亮显示
const today = new Date();
const isCurrentMonth = today.getFullYear() === currentYear && today.getMonth() === currentMonth;
const todayDate = isCurrentMonth ? today.getDate() : -1;
// 生成日历表格HTML
const calendarBody = document.getElementById(targetBodyId);
calendarBody.innerHTML = '';
// 将日期数组分成6行,每行7天
for (let i = 0; i < 6; i++) {
const row = document.createElement('tr');
for (let j = 0; j < 7; j++) {
const dayIndex = i * 7 + j;
if (dayIndex < calendarDays.length) {
const day = calendarDays[dayIndex];
const cell = document.createElement('td');
cell.textContent = day.date;
// 根据是否是当前月设置样式
if (day.isCurrentMonth) {
cell.classList.add('current-month');
// 如果是今天,添加高亮样式
if (day.date === todayDate) {
cell.classList.add('today');
}
} else {
cell.classList.add('other-month');
}
row.appendChild(cell);
}
}
calendarBody.appendChild(row);
}
}
</script>
</body>
</html>