当前位置:首页 > 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' });

使用第三方库

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

js 实现日历

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

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

相关文章

vue实现日历

vue实现日历

Vue 实现日历组件 使用 Vue 实现日历组件可以通过自定义开发或借助第三方库完成。以下是两种常见方法: 方法一:自定义日历组件 创建基础日历结构,利用 Vue 的响应式特性动态渲染日期。核心逻…

js类实现

js类实现

使用类实现 JavaScript 功能 在 JavaScript 中,类(Class)是一种语法糖,基于原型继承机制。通过 class 关键字可以更直观地定义对象模板。 基本类定义 class…

js手势实现

js手势实现

手势识别实现方法 在JavaScript中实现手势识别通常涉及监听触摸事件(touchstart、touchmove、touchend)或鼠标事件(mousedown、mousemove、mouseu…

js验证码的实现

js验证码的实现

验证码的基本实现原理 验证码(CAPTCHA)的核心目标是区分人类用户和自动化程序。JavaScript可用于生成或验证客户端验证码,但需注意纯前端验证可能被绕过,通常需结合后端验证。 纯前端验证码…

js实现定位

js实现定位

使用Geolocation API获取当前位置 在JavaScript中,可以通过浏览器内置的Geolocation API获取用户的地理位置信息。该API需要用户授权才能访问位置数据。 if (n…

js实现原理

js实现原理

JavaScript 实现原理 JavaScript 是一种解释型语言,其实现原理涉及多个核心组件和运行机制,包括引擎、运行时环境、事件循环等。 引擎与解释执行 现代 JavaScript 引擎(如…