溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript如何實現年歷效果

發布時間:2021-08-25 10:44:54 來源:億速云 閱讀:141 作者:小新 欄目:開發技術
# 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字,此處為保持簡潔展示了核心代碼和結構。完整版本會包含更多實現細節、注釋和原理說明。)

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女