js 实现日历
实现日历的基本思路
日历的核心功能是展示日期,并允许用户进行日期选择或导航。JavaScript 可以动态生成日历的 HTML 结构,并处理用户交互逻辑。
基础日历结构
日历通常包含头部(显示月份和年份)、星期标题(周一到周日)以及日期格子。以下是一个简单的 HTML 结构:
<div id="calendar">
<div class="header">
<button id="prev">←</button>
<h2 id="month-year"></h2>
<button id="next">→</button>
</div>
<div class="weekdays">
<div>Mon</div>
<div>Tue</div>
<div>Wed</div>
<div>Thu</div>
<div>Fri</div>
<div>Sat</div>
<div>Sun</div>
</div>
<div id="days" class="days"></div>
</div>
生成日历的 JavaScript 代码
以下代码动态生成日历的日期格子:
const monthYearElement = document.getElementById('month-year');
const daysElement = document.getElementById('days');
const prevButton = document.getElementById('prev');
const nextButton = document.getElementById('next');
let currentDate = new Date();
function renderCalendar() {
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
monthYearElement.textContent =
`${currentDate.toLocaleString('default', { month: 'long' })} ${year}`;
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
const daysInPrevMonth = new Date(year, month, 0).getDate();
daysElement.innerHTML = '';
// 填充上个月的日期(可选)
for (let i = firstDay === 0 ? 6 : firstDay - 1; i > 0; i--) {
const dayElement = document.createElement('div');
dayElement.classList.add('prev-month-day');
dayElement.textContent = daysInPrevMonth - i + 1;
daysElement.appendChild(dayElement);
}
// 填充当前月的日期
for (let i = 1; i <= daysInMonth; i++) {
const dayElement = document.createElement('div');
dayElement.textContent = i;
if (
i === new Date().getDate() &&
month === new Date().getMonth() &&
year === new Date().getFullYear()
) {
dayElement.classList.add('today');
}
daysElement.appendChild(dayElement);
}
// 填充下个月的日期(可选)
const totalCells = Math.ceil((firstDay + daysInMonth) / 7) * 7;
const remainingCells = totalCells - (firstDay + daysInMonth);
for (let i = 1; i <= remainingCells; i++) {
const dayElement = document.createElement('div');
dayElement.classList.add('next-month-day');
dayElement.textContent = i;
daysElement.appendChild(dayElement);
}
}
prevButton.addEventListener('click', () => {
currentDate.setMonth(currentDate.getMonth() - 1);
renderCalendar();
});
nextButton.addEventListener('click', () => {
currentDate.setMonth(currentDate.getMonth() + 1);
renderCalendar();
});
renderCalendar();
添加样式
日历需要基本的 CSS 样式来美化布局:
#calendar {
width: 300px;
font-family: Arial, sans-serif;
border: 1px solid #ccc;
border-radius: 5px;
padding: 10px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.weekdays {
display: grid;
grid-template-columns: repeat(7, 1fr);
text-align: center;
font-weight: bold;
margin-bottom: 5px;
}
.days {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 5px;
}
.days div {
padding: 5px;
text-align: center;
border-radius: 3px;
}
.today {
background-color: #007bff;
color: white;
}
.prev-month-day, .next-month-day {
color: #ccc;
}
进阶功能
-
日期选择
为日期格子添加点击事件,标记选中的日期:daysElement.addEventListener('click', (e) => { if (e.target.classList.contains('prev-month-day') || e.target.classList.contains('next-month-day')) { return; } const selectedDay = document.querySelector('.selected'); if (selectedDay) selectedDay.classList.remove('selected'); e.target.classList.add('selected'); }); -
事件标记
在特定日期上显示事件标记:const events = { '2023-11-15': 'Meeting', '2023-11-20': 'Birthday' }; function renderCalendar() { // ... 之前的代码 ... for (let i = 1; i <= daysInMonth; i++) { const dayElement = document.createElement('div'); dayElement.textContent = i; const dateKey = `${year}-${String(month + 1).padStart(2, '0')}-${String(i).padStart(2, '0')}`; if (events[dateKey]) { const eventSpan = document.createElement('span'); eventSpan.textContent = events[dateKey]; eventSpan.classList.add('event'); dayElement.appendChild(eventSpan); } daysElement.appendChild(dayElement); } } -
本地化
使用toLocaleString支持多语言:monthYearElement.textContent = currentDate.toLocaleString('en-US', { month: 'long', year: 'numeric' });
使用第三方库
如果需要更复杂的日历功能,可以考虑以下库:
- FullCalendar:功能强大的日历库,支持事件拖拽、视图切换等。
- Pikaday:轻量级的日期选择器。
- Flatpickr:现代化的日期时间选择器。







