Przyciski miesięcy, weekendy i klikanie w dni

Praktyka: kalendarz - JavaScript od podstaw: konsola (HTML/CSS/JS)

Kalendarz ożywa. Przyciski `#prev` i `#next` zmieniają miesiąc (przejście przez grudzień zwiększa rok), a funkcja `show` usuwa starą tabelę `replaceChildren()` i podpina nową. Komórki sobót i niedziel dostają klasę `weekend` (`classList.add`), a styl CSS koloruje je bez dotykania skryptu. Klikanie obsługuje JEDEN nasłuchiwacz na rodzicu (`#calendar`): zdarzenie z komórki "wypływa" do rodzica, a `e.target.closest('td')` mówi, którą komórkę kliknięto. To delegowanie zdarzeń: działa także dla tabel zbudowanych później.

<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="utf-8">
  <title>Kalendarz: miesiące i zdarzenia</title>
  <style>
    table { border-collapse: collapse; font-family: sans-serif; }
    th, td { border: 1px solid #94a3b8; width: 2.5em; height: 2em; text-align: center; }
    th { background: #e0e7ff; color: #1e1b4b; }
    td.weekend { background: #fee2e2; color: #991b1b; }
    td:hover { outline: 2px solid #6366f1; cursor: pointer; }
  </style>
</head>
<body>
  <button id="prev">&lt;</button>
  <strong id="title"></strong>
  <button id="next">&gt;</button>
  <div id="calendar"></div>
  <p id="selected">Kliknij dzień.</p>
  <script>
    const MONTHS = ['styczeń', 'luty', 'marzec', 'kwiecień', 'maj', 'czerwiec',
      'lipiec', 'sierpień', 'wrzesień', 'październik', 'listopad', 'grudzień'];
    const DAYS = ['Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So', 'Nd'];
    function buildWeeks(year, month) {
      const first = (new Date(year, month - 1, 1).getDay() + 6) % 7;
      const days = new Date(year, month, 0).getDate();
      const cells = [];
      for (let i = 0; i < first; i++) cells.push(null);
      for (let d = 1; d <= days; d++) cells.push(d);
      while (cells.length % 7 !== 0) cells.push(null);
      const weeks = [];
      for (let i = 0; i < cells.length; i += 7) {
        weeks.push(cells.slice(i, i + 7));
      }
      return weeks;
    }
    let year = 2026;
    let month = 11;

    function renderTable(year, month) {
      const table = document.createElement('table');
      const head = document.createElement('tr');
      for (const name of DAYS) {
        const th = document.createElement('th');
        th.textContent = name;
        head.appendChild(th);
      }
      table.appendChild(head);
      for (const week of buildWeeks(year, month)) {
        const tr = document.createElement('tr');
        week.forEach((day, i) => {
          const td = document.createElement('td');
          td.textContent = day === null ? '' : day;
          if (i >= 5) td.classList.add('weekend');
          tr.appendChild(td);
        });
        table.appendChild(tr);
      }
      return table;
    }

    function show() {
      document.getElementById('title').textContent = `${MONTHS[month - 1]} ${year}`;
      document.getElementById('calendar').replaceChildren(renderTable(year, month));
    }

    document.getElementById('prev').addEventListener('click', () => {
      month--;
      if (month === 0) {
        month = 12;
        year--;
      }
      show();
    });

    document.getElementById('next').addEventListener('click', () => {
      month++;
      if (month === 13) {
        month = 1;
        year++;
      }
      show();
    });

    document.getElementById('calendar').addEventListener('click', e => {
      const td = e.target.closest('td');
      if (!td || td.textContent === '') return;
      document.getElementById('selected').textContent =
        `Wybrano: ${td.textContent} ${MONTHS[month - 1]} ${year}`;
    });

    show();
  </script>
</body>
</html>

Ładowanie interaktywnego edytora... Jeśli się nie pojawi, włącz JavaScript.

Wszystkie lekcje kursu JavaScript od podstaw: konsola·Zaloguj się, aby zapisać postęp na koncie.