当前位置:首页 > 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
分享给朋友:

相关文章

vue怎么实现日历

vue怎么实现日历

实现日历组件的基本方法 使用Vue实现日历组件可以通过以下步骤完成。这里提供一个基础的实现思路,结合Vue 3的Composition API和模板语法。 安装依赖(如需要) npm inst…

js实现拖拽

js实现拖拽

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

js实现分页

js实现分页

实现分页的基本思路 分页功能通常需要处理数据分割、页码生成和用户交互。核心逻辑包括计算总页数、根据当前页截取数据、渲染页码按钮等。 前端分页实现(静态数据) 假设已有全部数据,仅需前端分页展示:…

js实现倒计时

js实现倒计时

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

vue实现js休眠

vue实现js休眠

Vue 中实现 JavaScript 休眠 在 Vue 中实现 JavaScript 休眠通常需要使用异步方式,以避免阻塞主线程。以下是几种常见方法: 使用 setTimeout 和 Promis…

js实现vue路由

js实现vue路由

Vue路由基础实现 使用Vue Router实现前端路由需要先安装并配置路由库。Vue Router是Vue.js官方的路由管理器。 安装Vue Router: npm install vue-r…