JavaScript如何实现年历效果

发布时间:2021-08-25 10:44:54 作者:小新
来源:亿速云 阅读:136
# JavaScript如何实现年历效果

在现代Web开发中,日历组件是常见的交互元素。本文将详细介绍如何使用纯JavaScript实现一个动态年历效果,涵盖核心逻辑、日期计算和DOM操作。

## 一、基础HTML结构

首先创建简单的HTML骨架,包含日历容器和导航按钮:

```html
<div class="calendar-container">
  <div class="calendar-header">
    <button id="prev-year">◀</button>
    <h2 id="current-year">2023</h2>
    <button id="next-year">▶</button>
  </div>
  <div id="months-container" class="months-grid"></div>
</div>

二、CSS基础样式

添加基础样式确保日历的可视化效果:

.months-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}

.month-container {
  border: 1px solid #ddd;
  padding: 10px;
}

.month-title {
  text-align: center;
  margin-bottom: 10px;
}

.days-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}

.day-header, .day-cell {
  text-align: center;
  padding: 5px;
}

.day-header {
  font-weight: bold;
  background: #f0f0f0;
}

三、JavaScript核心实现

1. 初始化变量

let currentYear = new Date().getFullYear();
const weekdays = ['日', '一', '二', '三', '四', '五', '六'];

2. 生成月份数据

function generateMonthData(year, month) {
  const firstDay = new Date(year, month, 1);
  const lastDay = new Date(year, month + 1, 0);
  
  // 计算月份开始于星期几(0-6)
  const startDay = firstDay.getDay();
  
  return {
    year,
    month,
    daysInMonth: lastDay.getDate(),
    startDay
  };
}

3. 渲染单个月份

function renderMonth(monthData) {
  const monthContainer = document.createElement('div');
  monthContainer.className = 'month-container';
  
  // 添加月份标题
  const monthTitle = document.createElement('h3');
  monthTitle.className = 'month-title';
  monthTitle.textContent = `${monthData.month + 1}月`;
  monthContainer.appendChild(monthTitle);
  
  // 创建星期标题行
  const daysHeader = document.createElement('div');
  daysHeader.className = 'days-grid';
  weekdays.forEach(day => {
    const dayHeader = document.createElement('div');
    dayHeader.className = 'day-header';
    dayHeader.textContent = day;
    daysHeader.appendChild(dayHeader);
  });
  
  // 创建日期格子
  const daysGrid = document.createElement('div');
  daysGrid.className = 'days-grid';
  
  // 添加空白格子(月初开始的星期几)
  for (let i = 0; i < monthData.startDay; i++) {
    const emptyCell = document.createElement('div');
    emptyCell.className = 'day-cell';
    daysGrid.appendChild(emptyCell);
  }
  
  // 添加日期数字
  for (let day = 1; day <= monthData.daysInMonth; day++) {
    const dayCell = document.createElement('div');
    dayCell.className = 'day-cell';
    dayCell.textContent = day;
    
    // 标记当天日期
    const today = new Date();
    if (today.getFullYear() === monthData.year && 
        today.getMonth() === monthData.month && 
        today.getDate() === day) {
      dayCell.classList.add('today');
    }
    
    daysGrid.appendChild(dayCell);
  }
  
  monthContainer.appendChild(daysHeader);
  monthContainer.appendChild(daysGrid);
  return monthContainer;
}

4. 渲染完整年历

function renderFullYearCalendar(year) {
  const monthsContainer = document.getElementById('months-container');
  monthsContainer.innerHTML = '';
  
  document.getElementById('current-year').textContent = year;
  
  // 生成并渲染12个月份
  for (let month = 0; month < 12; month++) {
    const monthData = generateMonthData(year, month);
    monthsContainer.appendChild(renderMonth(monthData));
  }
}

5. 添加年份导航功能

document.getElementById('prev-year').addEventListener('click', () => {
  currentYear--;
  renderFullYearCalendar(currentYear);
});

document.getElementById('next-year').addEventListener('click', () => {
  currentYear++;
  renderFullYearCalendar(currentYear);
});

四、高级功能扩展

1. 添加节日标记

const festivals = {
  '1-1': '元旦',
  '5-1': '劳动节',
  '10-1': '国庆节'
  // 可扩展更多节日
};

function markFestivals(dayCell, month, day) {
  const festivalKey = `${month + 1}-${day}`;
  if (festivals[festivalKey]) {
    const festivalMark = document.createElement('div');
    festivalMark.className = 'festival-mark';
    festivalMark.textContent = festivals[festivalKey];
    dayCell.appendChild(festivalMark);
  }
}

2. 实现日期选择功能

let selectedDate = null;

function setupDateSelection() {
  document.querySelectorAll('.day-cell').forEach(cell => {
    if (!cell.textContent.match(/^\d+$/)) return;
    
    cell.addEventListener('click', () => {
      // 移除之前选中的样式
      document.querySelectorAll('.selected').forEach(el => {
        el.classList.remove('selected');
      });
      
      // 添加新选中样式
      cell.classList.add('selected');
      selectedDate = new Date(
        currentYear,
        parseInt(cell.closest('.month-container')
          .querySelector('.month-title').textContent) - 1,
        parseInt(cell.textContent)
      );
    });
  });
}

3. 响应式布局优化

function checkScreenSize() {
  const monthsContainer = document.getElementById('months-container');
  if (window.innerWidth < 768) {
    monthsContainer.style.gridTemplateColumns = 'repeat(2, 1fr)';
  } else if (window.innerWidth < 480) {
    monthsContainer.style.gridTemplateColumns = '1fr';
  } else {
    monthsContainer.style.gridTemplateColumns = 'repeat(4, 1fr)';
  }
}

window.addEventListener('resize', checkScreenSize);

五、完整实现与初始化

// 初始化日历
document.addEventListener('DOMContentLoaded', () => {
  renderFullYearCalendar(currentYear);
  checkScreenSize();
});

六、总结

通过本文的实现,我们完成了: 1. 动态生成任意年份的年历 2. 正确的日期排列和星期对应 3. 基本的交互功能(年份导航) 4. 扩展功能(节日标记、日期选择)

这个实现完全基于原生JavaScript,不依赖任何第三方库,可以轻松集成到各种项目中。如需进一步优化,可以考虑: - 添加农历显示 - 实现月视图/周视图切换 - 增加事件提醒功能 “`

(注:实际文章约1500字,此处为保持简洁展示了核心代码和结构。完整版本会包含更多实现细节、注释和原理说明。)

推荐阅读:
  1. JavaScript实现拖拽效果
  2. Javascript怎么实现动态时钟效果

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

javascript

上一篇:Java流中如何收集数据解析

下一篇:C/C++中如何实现int数与多枚举值互转

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》