当前位置:首页 > 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 代码

以下代码动态生成日历的日期格子:

js 实现日历

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. 日期选择
    为日期格子添加点击事件,标记选中的日期:

    js 实现日历

    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实现验证

验证表单输入 使用JavaScript验证表单输入是常见的需求。可以通过监听表单提交事件,检查输入字段是否符合要求。 document.getElementById('myForm').addEve…

js防抖和节流实现

js防抖和节流实现

防抖(Debounce)的实现 防抖的核心思想是在事件被触发后,延迟执行回调函数。如果在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口大小调整等场景。 function debounce…

js实现换肤

js实现换肤

使用CSS变量实现换肤 通过CSS变量可以轻松实现主题切换功能。CSS变量在根元素中定义,通过JavaScript动态修改这些变量值。 :root { --primary-color: #349…

vue VUE实现日历组件功能

vue VUE实现日历组件功能

Vue 日历组件实现方法 基础日历结构 使用Vue的模板语法构建日历的HTML结构,通常包含头部(年月显示、切换按钮)和日历表格(星期标题和日期格子)。 <template> &l…

vue实现全年日历

vue实现全年日历

实现全年日历的基本思路 使用Vue实现全年日历需要结合日期计算、数据渲染和交互逻辑。核心在于生成全年12个月的日历数据,并通过组件化方式展示。以下是具体实现方法: 安装依赖(可选) 如需更便捷的日…

js实现驼峰

js实现驼峰

实现驼峰命名的几种方法 使用正则表达式和字符串替换 通过正则表达式匹配字符串中的特定模式(如下划线或短横线),并将其后的字母转换为大写,同时移除分隔符。 function toCamelCase(…