Calendar 年月変更 - Javascript

  • 作成日:
  • 最終更新日:2026/01/14

Calendar 年月変更

セレクトメニューで選択した年と月のカレンダーを表示します。「 前月 」「 次月 」をクリックすると前月と翌月のカレンダーの表示に変更します。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./style.css">
  <script src="./script.js"></script>
</head>
<body>
  <div>
    <div class="calendar-header">
      <button id="prev">◀ 前月</button>
      <select id="yearSelect"></select>
      <select id="monthSelect"></select>
      <button id="next">次月 ▶</button>
    </div>

    <table id="calendar">
      <thead>
        <tr>
          <th>日</th><th>月</th><th>火</th>
          <th>水</th><th>木</th><th>金</th><th>土</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </div>
  
</body>
</html>

style.css

table {
  border-collapse: collapse;
  width: 350px;
}
th, td {
  border: 1px solid #ccc;
  text-align: center;
  padding: 8px;
}
th {
  background: #f0f0f0;
}
.other-month {
  color: #aaa;
}
.today {
  background: #ffeb3b;
}
.holiday {
  color: red;
  font-weight: bold;
}
.sunday {
  color: red;
}
.saturday {
  color: blue;
}
#calendar {
  margin: 0 auto;
}
.calendar-header {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-bottom: 10px;
}
.calendar-header #yearSelect {
  font-size: 22px;
  padding: 2px;
}
.calendar-header #monthSelect {
  font-size: 22px;
  padding: 2px;
}

script.js

window.onload = function() {
  const today = new Date();

  let currentYear = today.getFullYear();
  let currentMonth = today.getMonth(); // 0〜11

  const monthTitle = document.getElementById('month');
  const tbody = document.querySelector('#calendar tbody');

  // ===== 年セレクト(例:2020〜2030)=====
  for (let y = 2020; y <= 2030; y++) {
    const option = document.createElement('option');
    option.value = y;
    option.textContent = `${y}年`;
    yearSelect.appendChild(option);
  }

  // ===== 月セレクト =====
  for (let m = 0; m < 12; m++) {
    const option = document.createElement('option');
    option.value = m;
    option.textContent = `${m + 1}月`;
    monthSelect.appendChild(option);
  }

  // 初期値(今日)
  yearSelect.value = today.getFullYear();
  monthSelect.value = today.getMonth();


  // セレクト変更時
  yearSelect.addEventListener('change', renderFromSelect);
  monthSelect.addEventListener('change', renderFromSelect);

  function renderFromSelect() {
    currentYear = Number(yearSelect.value);
    currentMonth = Number(monthSelect.value);
    renderCalendar(currentYear, currentMonth);
  }

  document.getElementById('prev').addEventListener('click', () => {
    currentMonth--;
    if (currentMonth < 0) {
      currentMonth = 11;
      currentYear--;
    }
    renderCalendar(currentYear, currentMonth);
  });

  document.getElementById('next').addEventListener('click', () => {
    currentMonth++;
    if (currentMonth > 11) {
      currentMonth = 0;
      currentYear++;
    }
    renderCalendar(currentYear, currentMonth);
  });

  function renderCalendar(year, month) {
    // セレクトメニューの値を変更
    yearSelect.value = year;
    monthSelect.value = month;

    tbody.innerHTML = '';

    const firstDay = new Date(year, month, 1).getDay();
    const lastDate = new Date(year, month + 1, 0).getDate();
    const prevLastDate = new Date(year, month, 0).getDate();

    let row = document.createElement('tr');

    // ===== 前月 =====
    for (let i = firstDay - 1; i >= 0; i--) {
      const cell = document.createElement('td');
      cell.textContent = prevLastDate - i;
      cell.classList.add('other-month');

      const weekDay = row.children.length;

      row.appendChild(cell);
    }

    // ===== 当月 =====
    for (let day = 1; day <= lastDate; day++) {
      const cell = document.createElement('td');
      cell.textContent = day;

      const weekDay = (firstDay + day - 1) % 7;
      if (weekDay === 0) cell.classList.add('sunday');
      if (weekDay === 6) cell.classList.add('saturday');

      if (
        year === today.getFullYear() &&
        month === today.getMonth() &&
        day === today.getDate()
      ) {
        cell.classList.add('today');
      }

      row.appendChild(cell);

      if ((firstDay + day) % 7 === 0) {
        tbody.appendChild(row);
        row = document.createElement('tr');
      }
    }

    // ===== 翌月 =====
    if (row.children.length > 0 && row.children.length < 7) {
      let nextMonthDay = 1;

      while (row.children.length < 7) {
        const cell = document.createElement('td');
        cell.textContent = nextMonthDay++;
        cell.classList.add('other-month');
        row.appendChild(cell);
      }

      tbody.appendChild(row);
    }

    tbody.appendChild(row);
  }

  // 初期表示
  renderCalendar(currentYear, currentMonth);

}