当前位置:首页 > JavaScript

js 实现日历

2026-01-16 12:12:33JavaScript

实现日历的基本思路

日历的核心功能是展示日期,并允许用户进行日期选择或导航。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;
}

进阶功能

  1. 日期选择
    为日期格子添加点击事件,标记选中的日期:

    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');
    });
  2. 事件标记
    在特定日期上显示事件标记:

    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);
      }
    }
  3. 本地化
    使用 toLocaleString 支持多语言:

    monthYearElement.textContent = 
      currentDate.toLocaleString('en-US', { month: 'long', year: 'numeric' });

使用第三方库

如果需要更复杂的日历功能,可以考虑以下库:

  • FullCalendar:功能强大的日历库,支持事件拖拽、视图切换等。
  • Pikaday:轻量级的日期选择器。
  • Flatpickr:现代化的日期时间选择器。

js 实现日历

标签: 日历js
分享给朋友:

相关文章

js 实现vue

js 实现vue

实现 Vue 的核心功能 在 JavaScript 中实现 Vue 的核心功能需要模拟数据绑定、虚拟 DOM 和响应式系统。以下是一个简化版的实现思路: 响应式系统 通过 Object.define…

js实现轮播

js实现轮播

实现基础轮播效果 使用HTML结构创建轮播容器和图片元素: <div class="carousel"> <div class="carousel-inner">…

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 使用JavaScript实现拖拽功能需要监听鼠标事件,包括mousedown、mousemove和mouseup。以下是实现的基本逻辑: const draggableEleme…

js实现轮播图

js实现轮播图

轮播图实现方法 基础HTML结构 <div class="slider"> <div class="slides"> <img src="image1.jpg…

js实现倒计时

js实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时功能可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是几种常见的实现方式: 使用 setInterv…

jquery.js

jquery.js

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,用于简化 HTML 文档遍历、事件处理、动画设计和 Ajax 交互。它的设计宗旨是“Write Less, Do Mor…