Materiał do egzaminu INF.03 — skrypty po stronie klienta w części praktycznej

JavaScript na egzaminie INF.03

Kurs oparty na arkuszach egzaminu praktycznego INF.03 z czerwca 2026. Podstawy języka, DOM i zdarzenia oraz sześć kompletnych wzorców zadań (galeria z oknem, karuzela, lista zamówień, dane JSON, kalkulator, plansza gry) z gotowymi rozwiązaniami i listą kontrolną.

23lekcji
4zadań praktycznych
46pytań „Sprawdź się”
Spis treści

W części praktycznej egzaminu INF.03 skrypty JavaScript są krótkie, ale precyzyjnie oceniane: komisja uruchamia stronę, wykonuje opisane w arkuszu czynności i sprawdza, czy skrypt zrobił dokładnie to, co trzeba. Kurs prowadzi od podstaw języka do wzorców powtarzających się w arkuszach – każdy wzorzec ma kompletny kod HTML, CSS i JavaScript oraz listę typowych błędów.

Pracuj z edytorem i przeglądarką otwartymi obok siebie. Do ćwiczeń są paczki ZIP z obrazami (znajdziesz je w lekcjach). Każda lekcja kończy się pytaniami „Sprawdź się”, a każda część – zadaniem praktycznym; wzorce ćwicz tak długo, aż napiszesz je z pamięci w kilka minut.

Część A

JavaScript na egzaminie i podstawy języka

Co sprawdza egzamin INF.03 w skryptach po stronie klienta, jak podłączyć skrypt do strony oraz zmienne, warunki, pętle, funkcje, tablice, obiekty i JSON.

Część A, lekcja 1

Jak wygląda JavaScript na egzaminie INF.03

W części praktycznej egzaminu INF.03 (150 minut) wykonujesz kompletną witrynę: bazę danych, strony HTML/CSS i skrypty. Skrypty po stronie klienta pisze się w JavaScript, a po stronie serwera w PHP. W arkuszach z czerwca 2026 (zadania 01–12) JavaScript pojawił się w ośmiu z dwunastu zadań, a w czterech pozostałych było PHP. Zadania JavaScript są krótkie (od kilku do kilkudziesięciu linii), ale każda linia jest oceniana, więc liczy się precyzja.

Typ zadaniaCo trzeba zrobićNajważniejsze techniki
karta produktu, galeriakliknięcie miniatury podmienia obraz główny; kliknięcie obrazu otwiera okno z powiększeniem; krzyżyk zamyka oknoquerySelector, .src, style.display, onclick z argumentem
rezerwacja, formularz dwuczęściowydwa przyciski przełączają aktywną część formularza i kolor przycisków; strzałki przewijają zdjęcia i nazwy miejscdisabled, style.backgroundColor, tablica obiektów, licznik z zawinięciem
dane pacjenta, receptyz obiektu/tablicy JSON wygenerować bloki z listami; puste pola pominąćpętla forEach, szablony napisów `${...}`, innerHTML, warunek na pusty napis
plansza do grykliknięcie pustego pola wstawia kółko lub krzyżyk, zmienia się gracz i widoczność napisówzmienna stanu, if, visibility, sprawdzanie src
licznik odwiedzinpo każdym wejściu zwiększyć licznik zapisany w przeglądarce i wypisać w stopcelocalStorage, parseInt, DOMContentLoaded
zamówienia w restauracjikliknięcie potrawy dodaje element listy; przycisk czyści; inny wyświetla alert i czyścicreateElement, append, alert, innerHTML = ""
atlas, wyszukiwarkadwie tablice (nazwy, opisy); kliknięcie obrazu lub wpisanie nazwy generuje tytuł i opistablice równoległe, includes, indexOf, tworzenie elementów DOM
kalkulatorsuwak i pole liczbowe zsynchronizowane; wynik zależy od zaznaczonej opcji; wypisanie dzisiejszej datyinput type=range/number/radio, :checked, Math.round, Date, padStart

Jak oceniany jest rezultat „Skrypty”

  • Kryteria skryptów sprawdza się w przeglądarce, wykonując akcje opisane w arkuszu (klik, wpisanie wartości), a gdy skrypt nie działa – w kodzie źródłowym.
  • Skrypt musi robić dokładnie to, co jest w poleceniu: dokładne teksty (np. „Zalecany rozmiar ramy to: 62 cali”), kolejność, kolory, nazwy klas i identyfikatorów podane w arkuszu. Nie wolno zmieniać nazw klas z projektu.
  • Zmienne i funkcje nazywasz znacząco, po polsku lub angielsku (podmienObraz, wyczyscZamowienie, currentPlayer) – nazwy typu a, x1, fun są obniżane w ocenie.
  • Kod może być w osobnym pliku main.js (zwykle wymagany przez arkusz) i musi być prawidłowo podłączony do strony.
Strategia

Na egzaminie najpierw wykonaj bazę i kwerendy (łatwe, szybkie punkty), potem HTML i CSS, a skrypty zostaw na koniec – ale nie pomijaj ich: każdy działający skrypt to osobne punkty. Skrypty JavaScript z arkuszy da się napisać w 5–15 minut, jeśli znasz wzorce z tego kursu.

Pliki ćwiczeniowe

W kursie znajdziesz paczki ZIP z obrazami do ćwiczeń (galeria, wycieczki, gra, zamówienia). HTML i CSS piszesz samodzielnie – dokładnie jak na egzaminie – a przykłady w lekcjach pokazują sprawdzone układy.

Sprawdź się — zadanie 1

Dlaczego nazwy funkcji i zmiennych w skrypcie powinny być znaczące?

Pokaż przykładową odpowiedź

Bo wymaga tego arkusz egzaminacyjny i ocenia je komisja: nazwa ma wskazywać cel (np. wyczyscZamowienie), a nie być przypadkowa (f1, x).

Sprawdź się — zadanie 2

Co zrobisz, gdy skrypt na egzaminie nie działa, a zostaje mało czasu?

Pokaż przykładową odpowiedź

Zostawię go z poprawną składnią i logiką w pliku (komisja może ocenić kod źródłowy), sprawdzę konsolę (F12) pod kątem błędu, a jeśli to nie pomoże – przejdę do kolejnych zadań i wrócę, gdy zostanie czas.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Wypisz w konsoli przeglądarki napis „Egzamin INF.03” i zadeklaruj stałą z liczbą pytań.

("Egzamin INF.03");
 liczbaPytan = 40;
Ćwiczenie interaktywne — uzupełnij kod

Znajdź w dokumencie element o klasie okno i zmień jego tekst.

document.(".okno"). = "Witaj";
Ćwiczenie interaktywne — popraw kod

Instrukcja nie wypisze tekstu w konsoli: nazwa obiektu jest napisana błędnie, a napis nie jest zamknięty. Popraw kod.

Część A, lekcja 2

Podłączenie skryptu do strony i narzędzia pracy

Skrypt można osadzić w HTML na trzy sposoby. Na egzaminie arkusz zwykle wymaga osobnego pliku (main.js, skrypty.js) połączonego ze stroną.

Sposoby dołączania JavaScript
<!-- 1. zewnętrzny plik: zalecany; defer = wykonanie po wczytaniu HTML -->
<script src="main.js" defer></script>

<!-- 2. skrypt wewnętrzny -->
<script>
  console.log("Witaj");
</script>

<!-- 3. atrybut zdarzenia w elemencie (spotykany w arkuszach: wywołanie funkcji po kliknięciu) -->
<button onclick="zamknijOkno()">Zamknij</button>

<!-- skrypt na końcu body też działa, bo elementy już istnieją -->
<script src="main.js"></script>
</body>
UmiejscowienieSkutek
<script src> w head bez deferskrypt uruchamia się przed zbudowaniem strony, więc querySelector(...) zwraca null (błąd „Cannot read properties of null”)
w head z deferwykonanie po wczytaniu HTML, ale przed zdarzeniem DOMContentLoaded – bezpieczny wybór
na końcu bodyelementy już istnieją; działa bez defer
funkcja wywoływana z atrybutu onclickskrypt mógł być wczytany wcześniej lub później – ważne, aby funkcja była globalna (na najwyższym poziomie pliku)
Najczęstszy błąd egzaminacyjny

Skrypt w head bez defer wykonuje się, zanim strona istnieje. Objaw w konsoli: Uncaught TypeError: Cannot read properties of null (reading 'style'). Rozwiązanie: defer, przeniesienie skryptu na koniec body albo pobieranie elementów wewnątrz funkcji wywoływanych po wczytaniu.

Konsola i debugowanie

  • F12 otwiera narzędzia deweloperskie: karta Console pokazuje błędy (czerwone) i wyniki console.log().
  • Karta Elements pozwala sprawdzić, czy element ma oczekiwany styl i klasy po wykonaniu skryptu, a Sources – ustawić punkt przerwania.
  • console.log(zmienna) to najszybszy sposób sprawdzenia wartości; console.table(tablica) pokazuje tablicę w tabeli.
  • Komunikat o błędzie zawiera nazwę pliku i numer linii – kliknij go, aby przejść do miejsca błędu.
Sprawdź się — zadanie 1

Dlaczego skrypt w sekcji head bez atrybutu defer może nie znaleźć elementów strony?

Pokaż przykładową odpowiedź

Bo przeglądarka wykonuje go w trakcie czytania HTML, zanim elementy z body zostaną utworzone; querySelector zwraca wtedy null.

Sprawdź się — zadanie 2

Jak sprawdzisz, jaką wartość ma zmienna w trakcie działania skryptu?

Pokaż przykładową odpowiedź

Wypiszę ją przez console.log(zmienna) i obejrzę w karcie Console narzędzi deweloperskich (F12) lub użyję punktu przerwania w Sources.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Podłącz plik skrypt.js na końcu strony tak, aby uruchomił się po wczytaniu elementów strony.

<body>
    <div class="okno"></div>
    < ="skrypt.js"></>
</body>
Ćwiczenie interaktywne — popraw kod

Skrypt jest podłączony niepoprawnie: atrybut ma zła nazwę, a znacznik nie jest zamknięty. Popraw kod HTML.

Ćwiczenie interaktywne — uzupełnij kod

Uruchom funkcję start dopiero po wczytaniu całego dokumentu.

document.("", start);
Ćwiczenie interaktywne — popraw kod

Skrypt w nagłówku strony nie widzi elementów, bo uruchamia się zbyt wcześnie. Dodaj atrybut, który opóźni wykonanie do końca wczytywania dokumentu.

Część A, lekcja 3

Zmienne, typy, operatory

DeklaracjaZasięgPrzypisanie ponowne
constblokowyniedozwolone (zawartość obiektu lub tablicy można zmieniać)
letblokowydozwolone
varfunkcyjnydozwolone; w nowym kodzie unikaj (spotkasz w starszych materiałach i na egzaminie)
Typy i konwersje
const imie = "Anna";             // string
let wiek = 17;                    // number (całkowite i rzeczywiste)
let aktywny = true;               // boolean
let nic = null;                   // null: celowy brak wartości
let niezdefiniowane;              // undefined: zmienna bez wartości

console.log(typeof imie, typeof wiek, typeof aktywny);   // string number boolean
console.log(Number("42"), parseInt("42px"), parseFloat("3.5"), String(7), (7).toString());
console.log("5" + 2, "5" - 2, "5" * "2");               // 52 3 10
console.log(isNaN(parseInt("abc")));                     // true
OperatoryPrzykładUwagi
arytmetyczne+ - * / % **, ++, --% – reszta z dzielenia (np. 7 % 3 = 1)
przypisania= += -= *= /=x += 2 to x = x + 2
porównania== != === !== < > <= >=w skryptach egzaminacyjnych używaj === (porównanie wartości i typu)
logiczne&&, ||, !&& – i, || – lub, ! – nie
napisy+, szablon `tekst ${zmienna}`szablon z odwrotnymi apostrofami wstawia wartości wyrażeń i może mieć wiele linii
Pole formularza zawsze daje napis

input.value jest napisem, nawet w polu type="number". Przed obliczeniami zamień na liczbę: Number(pole.value) lub parseInt(pole.value). Bez tego "160" + 5 daje "1605".

Sprawdź się — zadanie 1

Co wypisze console.log("10" + 5) i console.log("10" - 5)?

Pokaż przykładową odpowiedź

105 (sklejenie napisów) oraz 5 (odejmowanie zamienia napis na liczbę).

Sprawdź się — zadanie 2

Czym różni się const od let?

Pokaż przykładową odpowiedź

Zmiennej const nie można ponownie przypisać, a let można; oba mają zasięg blokowy.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Zadeklaruj stałą z nazwą, zmienną z licznikiem i zwiększ licznik o 1.

 nazwa = "Rower";
 licznik = 0;
licznik;
Ćwiczenie interaktywne — uzupełnij kod

Wylicz cenę po rabacie 15% i wypisz napis z wartością (szablon w odwróconych apostrofach).

const cena = 200;
const rabat = 0.15;
const doZaplaty = cena  (1 - rabat);
console.log(Do zapłaty:  zł);
Ćwiczenie interaktywne — popraw kod

Wynik dodawania jest sklejony jako tekst („52”), bo wartość z pola jest napisem. Zamień ją na liczbę, aby wynik wynosił 7.

Ćwiczenie interaktywne — popraw kod

Próba zmiany stałej kończy się błędem. Popraw deklarację tak, aby zmienną można było zwiększać.

Ćwiczenie interaktywne — uzupełnij kod

Użyj operatora reszty z dzielenia, aby sprawdzić parzystość, oraz porównania ścisłego.

const liczba = 8;
const parzysta = liczba  2  0;
console.log(parzysta);

Część A, lekcja 4

Instrukcje warunkowe

Warunki
const temperatura = 18;
if (temperatura >= 25) {
    console.log("gorąco");
} else if (temperatura >= 15) {
    console.log("ciepło");
} else {
    console.log("zimno");
}

// operator trójargumentowy: warunek ? gdyPrawda : gdyFałsz
const opis = temperatura > 20 ? "lato" : "nie lato";

// switch przy wielu wartościach jednej zmiennej
switch (opis) {
    case "lato": console.log("kąpiel"); break;
    default:     console.log("kurtka");
}

// typowe w arkuszach: ustawienie współczynnika zależnie od wyboru
let wspolczynnik = 0.26;
if (wybor === "szosa") wspolczynnik = 0.3;
if (wybor === "trekking") wspolczynnik = 0.28;
Wartości „fałszywe”

W warunku fałszywe są: false, 0, "" (pusty napis), null, undefined i NaN. Dlatego if (recepta.lek2) pomija pusty lek, ale if (recepta.lek2 != "") robi to jawniej – w arkuszu podobne warunki są wprost wymagane.

OperatorZnaczenie
===, !==równość i różność z kontrolą typu (zalecane); == porównuje po konwersji typów
<, <=, >, >=porównania liczb (i napisów alfabetycznie)
&&, ||, !i, lub, negacja – łączenie warunków
Sprawdź się — zadanie 1

Jak sprawdzisz, że napis lek2 nie jest pusty?

Pokaż przykładową odpowiedź

if (lek2 !== "") { ... } lub krócej if (lek2) { ... }.

Sprawdź się — zadanie 2

Kiedy użyjesz switch zamiast else if?

Pokaż przykładową odpowiedź

Gdy jedna zmienna jest porównywana z wieloma konkretnymi wartościami; pamiętaj o break i default.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Wypisz „gorąco” dla temperatury od 25 stopni, „ciepło” od 15 i „zimno” w pozostałych przypadkach.

const t = 18;
 (t >= 25) {
    console.log("gorąco");
}  (t  15) {
    console.log("ciepło");
}  {
    console.log("zimno");
}
Ćwiczenie interaktywne — popraw kod

Warunek ma sprawdzić, czy napis wybor jest równy „szosa”, ale zamiast porównania stoi przypisanie. Popraw kod.

Ćwiczenie interaktywne — uzupełnij kod

Użyj operatora trójargumentowego oraz instrukcji switch.

const opis = temperatura > 20  "lato"  "nie lato";
 (opis) {
    case "lato": console.log("kąpiel"); ;
    default: console.log("kurtka");
}
Ćwiczenie interaktywne — popraw kod

Pole lek2 ma być pominięte, gdy jest puste, ale warunek sprawdza coś innego. Popraw go tak, aby kod wykonał się tylko przy niepustym napisie.

Ćwiczenie interaktywne — uzupełnij kod

Połącz dwa warunki: wiek co najmniej 18 oraz zgoda wyrażona.

if (wiek >= 18  zgoda) {
    console.log("można");
}
if (wiek < 18  !zgoda) {
    console.log("nie można");
}

Część A, lekcja 5

Pętle

Pętle
for (let i = 0; i < 5; i++) {          // znana liczba powtórzeń
    console.log(i);
}
let n = 3;
while (n > 0) { console.log(n); n--; }

const miasta = ["Radom", "Kielce", "Lublin"];
for (const miasto of miasta) console.log(miasto);      // po wartościach
miasta.forEach((miasto, indeks) => console.log(indeks, miasto));   // z indeksem
PętlaKiedy
forznana liczba powtórzeń lub potrzebny indeks (plansza, tabela)
whilepowtarzanie, dopóki warunek jest prawdziwy – pamiętaj o zmianie zmiennej w treści pętli
for...of, forEachprzejście po wszystkich elementach tablicy
break, continueprzerwanie pętli, przejście do następnego obrotu
Pętla bez końca

while (n > 0) { ... } bez n-- nigdy się nie zakończy i zawiesi kartę przeglądarki. Sprawdź, czy zmienna sterująca zmienia się w każdym obrocie.

Sprawdź się — zadanie 1

Którą pętlą przejdziesz po wszystkich elementach tablicy bez użycia indeksu?

Pokaż przykładową odpowiedź

for (const element of tablica) lub tablica.forEach(element => ...).

Sprawdź się — zadanie 2

Ile razy wykona się for (let i = 1; i <= 5; i++)?

Pokaż przykładową odpowiedź

Pięć razy (i = 1, 2, 3, 4, 5).

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Wypisz liczby od 0 do 4 pętlą for.

 (let i = 0; i  5; i) {
    console.log(i);
}
Ćwiczenie interaktywne — popraw kod

Pętla while odlicza od 3 do 1, ale nigdy się nie kończy. Popraw kod.

Ćwiczenie interaktywne — uzupełnij kod

Wypisz każde miasto z tablicy: raz pętlą po wartościach, raz metodą forEach z indeksem.

const miasta = ["Radom", "Kielce", "Lublin"];
for (const miasto  miasta) console.log(miasto);
miasta.((miasto, ) => console.log(indeks, miasto));
Ćwiczenie interaktywne — popraw kod

Pętla ma zsumować elementy tablicy, ale suma jest zerowana w każdym obrocie. Popraw kod.

Część A, lekcja 6

Funkcje i ich wywoływanie z HTML

Funkcja to nazwany fragment kodu, który można wywołać wielokrotnie. W arkuszach egzaminacyjnych funkcje są uruchamiane po zdarzeniu, najczęściej przez atrybut onclick elementu HTML.

Funkcje z parametrami i bez
function otworzOkno() {                         // bez parametrów
    document.querySelector(".okno").style.display = "block";
}

function podmienObraz(nazwaPliku) {                // z parametrem
    document.querySelector(".obraz").src = `img/${nazwaPliku}`;
}

function sredniaOcen(oceny) {                      // z wartością zwracaną
    let suma = 0;
    for (const ocena of oceny) suma += ocena;
    return suma / oceny.length;
}
console.log(sredniaOcen([5, 4, 3]).toFixed(2));    // "4.00"

const kwadrat = x => x * x;                        // funkcja strzałkowa
Wywołanie funkcji z elementu HTML
<img class="miniatura" src="img/rower2.svg" alt="miniatura" onclick="podmienObraz('rower2.svg')">
<button onclick="otworzOkno()">Powiększ</button>
<input type="number" id="wzrost" onchange="obliczRozmiar()">
<button onclick="zmienSekcje('uczestnik')">Uczestnik</button>
  • Funkcja ma zasięg globalny, jeśli jest zadeklarowana na najwyższym poziomie pliku – tylko wtedy widzi ją atrybut onclick.
  • Argument tekstowy w atrybucie HTML zapisuj w apostrofach wewnątrz cudzysłowów: onclick="podmienObraz('rower2.svg')".
  • Atrybut onclick="funkcja(this)" przekazuje do funkcji element, który został kliknięty (this) – wzorzec użyty w planszy gry.
  • Nie dodawaj nawiasów przy przypisaniu funkcji do zdarzenia w JS: przycisk.onclick = funkcja (bez ()), bo funkcja() wykona się od razu.
Pułapka: wywołanie zamiast przekazania

document.addEventListener("DOMContentLoaded", licznik()) wykona licznik() natychmiast i przekaże do zdarzenia jego wynik (undefined). Poprawnie: addEventListener("DOMContentLoaded", licznik). Podobnie onclick="funkcja" w HTML nic nie wykona – potrzebne są nawiasy.

Sprawdź się — zadanie 1

Co oznacza przekazanie this w onclick="zaznaczPole(this)"?

Pokaż przykładową odpowiedź

Do funkcji trafia kliknięty element (np. komórka tabeli z obrazem), więc funkcja może zmienić jego właściwości bez wyszukiwania.

Sprawdź się — zadanie 2

Dlaczego wywołanie addEventListener("click", funkcja()) jest błędem?

Pokaż przykładową odpowiedź

Nawiasy powodują natychmiastowe wywołanie funkcji, a do obsługi zdarzenia trafia jej wynik zamiast samej funkcji; powinno być addEventListener("click", funkcja).

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Napisz funkcję z parametrem, która podmienia obraz, i funkcję zwracającą średnią.

 podmienObraz(nazwaPliku) {
    document.querySelector(".obraz").src = `img/${nazwaPliku}`;
}
function srednia(oceny) {
    let suma = 0;
    for (const ocena of oceny) suma += ocena;
     suma / oceny.length;
}
Ćwiczenie interaktywne — uzupełnij kod

Wywołaj funkcje z elementów HTML: kliknięcie miniatury i przycisku.

<img class="miniatura" src="img/rower2.svg" ="podmienObraz('rower2.svg')">
<button onclick="otworzOkno">Powiększ</button>
Ćwiczenie interaktywne — popraw kod

Obsługa zdarzenia uruchamia funkcję natychmiast, a nie po kliknięciu. Popraw przypisanie funkcji.

Ćwiczenie interaktywne — popraw kod

Funkcja ma zwrócić kwadrat liczby, ale po wywołaniu wynikiem jest undefined. Popraw kod.

Ćwiczenie interaktywne — uzupełnij kod

Zapisz tę samą funkcję jako funkcję strzałkową.

const kwadrat = x  x * x;

Część A, lekcja 7

Tablice w JavaScript

Tablica przechowuje uporządkowaną listę wartości pod jedną nazwą. Elementy numerujemy od zera. Tablice służą w arkuszach do list nazw, ścieżek obrazów, opisów i cen.

Tablice
const drzewa = ["buk", "lipa", "wierzba"];
console.log(drzewa[0], drzewa.length);          // buk 3
drzewa.push("dąb");                              // dodanie na końcu
console.log(drzewa.includes("lipa"));            // true: czy zawiera
console.log(drzewa.indexOf("wierzba"));          // 2: pozycja lub -1
drzewa.forEach((drzewo, i) => console.log(i, drzewo));

// tablice równoległe: ten sam indeks = to samo drzewo
const opisy = ["Duże drzewo...", "Drzewo o szerokiej koronie...", "Rośnie nad wodą..."];
const gdzie = drzewa.indexOf("lipa");
console.log(`${drzewa[gdzie]}: ${opisy[gdzie]}`);
OperacjaZapis
odczyt elementu, długośćt[0], t.length; ostatni element: t[t.length - 1]
dodanie / usunięcie na końcut.push(x) / t.pop()
czy zawiera, pozycjat.includes(x) (true/false), t.indexOf(x) (indeks lub −1)
pętlat.forEach(el => ...), for (const el of t)
nowa tablica z wynikamit.map(el => ...), t.filter(el => warunek)
sortowanie, złączeniet.sort(), t.join(", ")
Indeksy numerujemy od zera

Pierwszy element ma indeks 0, a ostatni length - 1. Błąd o 1 w indeksie to jedna z najczęstszych przyczyn błędnego wyniku skryptu. W karuzeli wycieczek poprawne wartości numeru to 0, 1, 2 – przekroczenie zakresu (3 lub −1) wymaga zawinięcia.

Sprawdź się — zadanie 1

Jak sprawdzić, czy wpisana nazwa drzewa jest w tablicy nazw?

Pokaż przykładową odpowiedź

drzewa.includes(nazwa) zwraca true lub false; pozycję zwróci drzewa.indexOf(nazwa).

Sprawdź się — zadanie 2

Jak odczytać ostatni element tablicy t?

Pokaż przykładową odpowiedź

t[t.length - 1].

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Utwórz tablicę, odczytaj pierwszy element i długość, dodaj element na końcu.

const drzewa = "buk", "lipa", "wierzba";
console.log(drzewa[], drzewa.);
drzewa.("dąb");
Ćwiczenie interaktywne — uzupełnij kod

Sprawdź, czy tablica zawiera napis, i znajdź jego pozycję.

console.log(drzewa.("lipa"));
const gdzie = drzewa.("wierzba");
Ćwiczenie interaktywne — popraw kod

Odczyt ostatniego elementu tablicy zwraca undefined, bo indeksy liczymy od zera. Popraw wyrażenie.

Ćwiczenie interaktywne — uzupełnij kod

Utwórz nową tablicę podwojonych liczb oraz tablicę liczb większych od 15.

const liczby = [10, 20, 30];
const podwojone = liczby.(x => x * 2);
const duze = liczby.(x => x  15);

Część A, lekcja 8

Obiekty w JavaScript

Obiekt grupuje powiązane dane jako pary klucz: wartość, np. jedną wycieczkę czy jednego pacjenta. W arkuszach dane najczęściej mają postać tablicy obiektów, po której przechodzisz pętlą.

Tablica obiektów (typowa struktura w arkuszu)
const wycieczki = [
    { obraz: "img/1.svg", miejsce: "Barcelona" },
    { obraz: "img/2.svg", miejsce: "Rzym" },
    { obraz: "img/3.svg", miejsce: "Londyn" }
];
console.log(wycieczki[1].miejsce);               // Rzym
wycieczki.forEach(w => console.log(w.miejsce, w.obraz));

const pacjent = {
    imie: "Agnieszka",
    nazwisko: "Nowak",
    recepty: [
        { data: "8.03.2025", kod: "1220", lek1: "Witamina C", lek2: "Potas", lek3: "" },
        { data: "13.05.2025", kod: "2913", lek1: "Melatonina", lek2: "", lek3: "" }
    ]
};
console.log(pacjent.recepty[0].lek1, pacjent["imie"], pacjent.recepty.length);
OperacjaZapis
odczyt własnościo.nazwa lub o["nazwa"] (druga postać także ze zmienną: o[klucz])
zmiana lub dodanie własnościo.cena = 20;
sprawdzenie klucza"cena" in o
klucze i wartościObject.keys(o), Object.values(o)
obiekt w tablicy, tablica w obiekciepacjent.recepty[0].lek1 – czytaj od lewej do prawej
Pułapka: kropka i nawiasy

Przy kluczu zapisanym w zmiennej nie możesz użyć kropki: o.klucz szuka własności o nazwie „klucz”. Poprawnie: o[klucz].

Sprawdź się — zadanie 1

Jak odczytać pierwszy lek z drugiej recepty pacjenta?

Pokaż przykładową odpowiedź

pacjent.recepty[1].lek1 – indeksy zaczynają się od 0.

Sprawdź się — zadanie 2

Jak przejść po wszystkich obiektach tablicy wycieczki i wypisać miejsce?

Pokaż przykładową odpowiedź

wycieczki.forEach(w => console.log(w.miejsce)); lub for (const w of wycieczki) ....

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Utwórz obiekt wycieczki i odczytaj jego własności na dwa sposoby.

const wycieczka = { obraz: "img/1.svg", miejsce: "Barcelona" };
console.log(wycieczkamiejsce);
console.log(wycieczka);
Ćwiczenie interaktywne — uzupełnij kod

Wypisz miejsce każdej wycieczki z tablicy obiektów.

const wycieczki = [{ miejsce: "Rzym" }, { miejsce: "Londyn" }];
wycieczki.(w => console.log(w));
Ćwiczenie interaktywne — popraw kod

Odczyt pierwszego leku z drugiej recepty pacjenta jest zapisany błędnie. Popraw wyrażenie (indeksy zaczynają się od 0).

Ćwiczenie interaktywne — popraw kod

Klucz jest zapisany w zmiennej, ale kropka szuka własności o nazwie „klucz”. Popraw odczyt.

Część A, lekcja 9

JSON i dane wklejone z pliku

W arkuszach dane często dostajesz w pliku tekstowym (dane.json, do_strony.txt) – wklejasz je do skryptu jako gotową strukturę. Zapis JSON jest bardzo podobny do obiektów JavaScript.

JSON i jego użycie
// 1. struktura wklejona do skryptu jako zmienna
const dane = {
    "id": "1",
    "imie": "Agnieszka",
    "recepty": [
        { "id": "0", "data": "8.03.2025", "kod": "1220", "lek1": "Witamina C", "lek2": "Potas", "lek3": "Syrop" },
        { "id": "1", "data": "23.04.2025", "kod": "4634", "lek1": "APAP", "lek2": "Witamina B", "lek3": "" }
    ]
};
console.log(dane.recepty.length);          // 2

// 2. zamiana napisu JSON na obiekt i odwrotnie
const napis = '{"nazwa": "Ala", "oceny": [5, 4]}';
const obiekt = JSON.parse(napis);
console.log(obiekt.oceny[0]);              // 5
console.log(JSON.stringify(obiekt));       // {"nazwa":"Ala","oceny":[5,4]}
  • W JSON klucze i teksty są w podwójnych cudzysłowach, nie ma komentarzy, a ostatni element listy nie ma przecinka na końcu.
  • Gdy w treści zadania napisano, że tablica może zostać rozbudowana o nowe elementy, skrypt musi używać pętli po length tablicy (a nie na sztywno trzech elementów) – inaczej straci punkty przy sprawdzaniu z innymi danymi.
  • Wartości mogą być puste ("") – należy je pominąć w wyniku (patrz wzorzec „recepty”).
Dane z serwera

Gdy dane pochodzą z serwera, pobierasz je funkcją fetch() i zamieniasz przez .json(); w prostych arkuszach egzaminacyjnych wystarcza wklejona struktura.

Sprawdź się — zadanie 1

Co oznacza wymaganie, że w tablicy mogą pojawić się nowe elementy?

Pokaż przykładową odpowiedź

Skrypt ma działać dla dowolnej liczby elementów, więc trzeba użyć pętli po całej tablicy (forEach, for...of, length), a nie odwoływać się do indeksów na sztywno.

Sprawdź się — zadanie 2

Czym różni się obiekt JavaScript od zapisu JSON?

Pokaż przykładową odpowiedź

JSON to tekstowy format danych z kluczami i napisami w podwójnych cudzysłowach, bez funkcji i komentarzy; obiekt JS jest strukturą w pamięci. JSON.parse i JSON.stringify zamieniają jedno na drugie.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Zamień tekst JSON na obiekt oraz obiekt na tekst.

const tekst = '{"miejsce":"Rzym","cena":300}';
const dane = JSON.(tekst);
console.log(dane.cena);
const z_powrotem = JSON.(dane);
Ćwiczenie interaktywne — popraw kod

Ten tekst nie jest poprawnym JSON-em: klucze i napisy muszą być w cudzysłowach. Popraw tekst.

Ćwiczenie interaktywne — uzupełnij kod

Dane wklejone z pliku to tablica obiektów; wypisz imię i nazwisko każdego pacjenta.

const pacjenci = [{ imie: "Anna", nazwisko: "Nowak" }, { imie: "Jan", nazwisko: "Kot" }];
 (const p  pacjenci) {
    console.log(`${p.imie} ${p.nazwisko}`);
}
Ćwiczenie interaktywne — popraw kod

Po odczytaniu JSON-u zmienna jest nadal tekstem, więc odwołanie do własności zwraca undefined. Popraw kod.

Zadanie praktyczne

Funkcje, tablice i obiekty: statystyki oceny

Szacowany czas: 35 minZakres: Lekcje 1–7Forma: plik oceny.js i strona oceny.html

Zadanie

Przygotuj stronę, która po wczytaniu wylicza i wypisuje statystyki ocen ucznia z tablicy obiektów. Układ zrób według własnego pomysłu, ale zachowaj wymagania poniżej.

Założenia

  • Tablica obiektów przedmioty: nazwa przedmiotu i tablica ocen (min. 4 przedmioty, jeden z pustą tablicą ocen).
  • Funkcja sredniaPrzedmiotu(oceny) zwraca średnią lub 0 dla pustej tablicy; funkcja najlepszyPrzedmiot() zwraca nazwę przedmiotu z najwyższą średnią.
  • Po wczytaniu strony skrypt wpisuje w paragrafie z id="wynik" tekst „Najlepszy przedmiot: <nazwa> (średnia <wartość>)” z średnią zaokrągloną do dwóch miejsc po przecinku.
  • Dodaj przycisk „Dodaj ocenę 5 do matematyki” z atrybutem onclick; po kliknięciu ocena trafia do tablicy, a wynik zostaje wyliczony ponownie (bez przeładowania strony).
  • Kod w osobnym pliku podłączonym z defer; nazwy zmiennych i funkcji po polsku; brak błędów w konsoli.

Ocenie podlegać będzie

  • poprawność obliczeń i obsługa pustej tablicy,
  • podział na funkcje z parametrami,
  • poprawne dołączenie skryptu i wywołanie z HTML,
  • znaczące nazwy i czytelny kod.
Wskazówki
  • Zaokrąglenie: toFixed(2).
  • Wywołaj funkcję wyliczającą wynik najpierw przy ładowaniu, a potem po kliknięciu przycisku.
  • Lekcje 5 i 6.

Część B

DOM, zdarzenia i formularze

Wyszukiwanie i zmiana elementów, style i klasy, zdarzenia, tworzenie elementów, pola formularzy, liczby i daty oraz localStorage.

Część B, lekcja 10

DOM: wyszukiwanie elementów i odczyt wartości

DOM (Document Object Model) to drzewo obiektów reprezentujące stronę. Skrypt „widzi” stronę przez obiekt document i może odczytać oraz zmienić każdy element. Do wyszukiwania w zadaniach egzaminacyjnych wystarczą trzy metody:

MetodaZwracaPrzykład
document.querySelector(selektor)pierwszy pasujący element lub nullquerySelector("#wynik"), (".obraz"), ("ul"), ("input[type='range']")
document.querySelectorAll(selektor)wszystkie pasujące (lista, po której można użyć forEach)querySelectorAll("input[name='wyzywienie']")
document.getElementById(id)element o danym identyfikatorze (bez #)getElementById("prawy2")

Selektor w querySelector jest taki sam jak w CSS: #id, .klasa, znacznik, znacznik.klasa, rodzic potomek, [atrybut='wartość'], :checked.

Co odczytać / zmienićWłaściwośćPrzykład
tekst (bez HTML)textContentwynik.textContent = "Gotowe"
zawartość z HTMLinnerHTMLblok.innerHTML = "<h2>Tytuł</h2>"
wartość pola formularzavalueconst wzrost = Number(pole.value)
źródło obrazu, adressrc, hrefobraz.src = "img/rower2.svg"
dowolny atrybutgetAttribute(), setAttribute()img.setAttribute("alt", "miniatura")
zaznaczenie pola wyboru / radiocheckedif (zgoda.checked) { ... }
blokada poladisabledpole.disabled = true
Przykład: odczyt pola, zapis wyniku
<input type="text" id="imie">
<button onclick="przywitaj()">Przywitaj</button>
<p id="powitanie"></p>

<script>
function przywitaj() {
    const imie = document.querySelector("#imie").value;       // odczyt
    const akapit = document.querySelector("#powitanie");
    akapit.textContent = `Cześć, ${imie}!`;                   // zapis
}
</script>
innerHTML a bezpieczeństwo

innerHTML interpretuje wstawiony napis jako HTML. Jeśli wstawiasz tekst wpisany przez użytkownika, użyj textContent (zapobiega atakom XSS). W zadaniach egzaminacyjnych generujących własne elementy z danych w skrypcie innerHTML jest dopuszczalny.

Sprawdź się — zadanie 1

Czym różni się querySelector od querySelectorAll?

Pokaż przykładową odpowiedź

querySelector zwraca pierwszy pasujący element (lub null), a querySelectorAll – listę wszystkich pasujących elementów.

Sprawdź się — zadanie 2

Jak odczytasz liczbę wpisaną w polu type="number" o id wzrost jako liczbę, a nie napis?

Pokaż przykładową odpowiedź

Number(document.querySelector("#wzrost").value) lub parseInt(...).

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Znajdź element o identyfikatorze wynik, wszystkie elementy o klasie miniatura i pierwszy z nich.

const wynik = document.("wynik");
const miniatury = document.(".miniatura");
const pierwsza = document.(".miniatura");
Ćwiczenie interaktywne — uzupełnij kod

Odczytaj wartość pola tekstowego o identyfikatorze imie i wstaw tekst do akapitu.

const imie = document.getElementById("imie").;
document.querySelector("p"). = "Witaj, " + imie;
Ćwiczenie interaktywne — popraw kod

Selektor klasy w querySelector wymaga kropki, a identyfikatora – znaku #. Popraw oba selektory.

Ćwiczenie interaktywne — popraw kod

Pętla ma ustawić tekst „x” w każdej miniaturze, ale querySelector zwraca tylko jeden element. Popraw kod.

Część B, lekcja 11

Style, klasy i stan elementów z poziomu JavaScript

Skrypt może zmieniać wygląd elementów przez właściwość style (pojedyncze style inline) lub przez classList (przełączanie klas zdefiniowanych w CSS). W arkuszach egzaminacyjnych wymagane bywa jedno albo drugie – czytaj dokładnie: „przez zastosowanie odpowiedniej właściwości CSS”.

style i classList
const okno = document.querySelector(".okno");
okno.style.display = "block";                 // pokaż (element wcześniej: display: none w CSS)
okno.style.display = "none";                  // ukryj, element nie zajmuje miejsca
okno.style.visibility = "hidden";             // ukryj, ale miejsce zostaje
okno.style.visibility = "visible";

const przycisk = document.querySelector("#uczestnikBtn");
przycisk.style.backgroundColor = "dodgerblue";   // właściwości CSS w camelCase: background-color → backgroundColor
przycisk.style.color = "#ffffff";
przycisk.style.fontSize = "150%";

przycisk.classList.add("aktywny");            // dodaj klasę
przycisk.classList.remove("aktywny");         // usuń klasę
przycisk.classList.toggle("aktywny");         // przełącz
console.log(przycisk.classList.contains("aktywny"));
CSSJavaScript (style)
background-colorstyle.backgroundColor
font-sizestyle.fontSize
border-radiusstyle.borderRadius
display, visibility, opacitystyle.display, style.visibility, style.opacity
z-indexstyle.zIndex

Blokowanie pól formularza

Przełączanie aktywnych kontrolek
function zmienSekcje(wybrana) {
    const pola1 = document.querySelectorAll("#sekcja1 input");
    const pola2 = document.querySelectorAll("#sekcja2 input, #sekcja2 select");
    const uczestnik = wybrana === "uczestnik";
    pola1.forEach(p => p.disabled = !uczestnik);        // true = pole nieaktywne
    pola2.forEach(p => p.disabled = uczestnik);
    document.querySelector("#uczestnikBtn").style.backgroundColor = uczestnik ? "dodgerblue" : "skyblue";
    document.querySelector("#rezerwacjaBtn").style.backgroundColor = uczestnik ? "skyblue" : "dodgerblue";
}
display czy visibility

display: none usuwa element z układu strony (pozostałe elementy się przesuwają), a visibility: hidden tylko go ukrywa. Arkusz zwykle precyzuje: „staje się ukryty” albo „zostaje usunięty zastosowaniem właściwości CSS”. W razie wątpliwości użyj tej właściwości, którą arkusz wymienia przy pierwszym pojawieniu się elementu (np. display: none w CSS bloku okna).

Sprawdź się — zadanie 1

Jak zapiszesz w JavaScript właściwość CSS background-color?

Pokaż przykładową odpowiedź

element.style.backgroundColor = "kolor" (camelCase).

Sprawdź się — zadanie 2

Jak zablokujesz pole formularza?

Pokaż przykładową odpowiedź

Ustawiając pole.disabled = true (odblokowanie: false).

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Ukryj okno, pokaż je i zmień kolor tła elementu.

const okno = document.querySelector(".okno");
okno.style. = "none";
okno.style.display = "";
okno.style. = "lightblue";
Ćwiczenie interaktywne — uzupełnij kod

Dodaj klasę, usuń klasę i przełącz klasę elementu.

el.classList.("aktywny");
el.classList.("aktywny");
el.classList.("aktywny");
Ćwiczenie interaktywne — popraw kod

W JavaScript nazwy właściwości stylu zapisujemy w camelCase, a wartości jako napisy. Popraw przypisanie.

Ćwiczenie interaktywne — popraw kod

Pole ma zostać wyłączone, a przycisk ukryty, ale zapisy są niepoprawne. Popraw kod.

Część B, lekcja 12

Zdarzenia: onclick, addEventListener, onchange

Zdarzenie to sygnał, że coś się stało (kliknięcie, zmiana wartości, wczytanie strony). Program przypisuje do zdarzenia funkcję, która ma się wykonać.

SposóbPrzykładKiedy
atrybut w HTML<button onclick="zamknijOkno()">najkrócej; często wymagany przez arkusz („kliknięcie wywołuje funkcję”)
właściwość obiektuprzycisk.onclick = zamknijOkno;bez nawiasów po nazwie funkcji
addEventListenerprzycisk.addEventListener("click", zamknijOkno);zalecany; wiele funkcji na jedno zdarzenie
ZdarzenieKiedy zachodziTypowy użytek na egzaminie
click (onclick)kliknięcie mysząprzyciski, obrazy, komórki tabeli, bloki z potrawami
change (onchange)zatwierdzenie zmiany wartości (suwak po puszczeniu, lista po wyborze)pola formularza
input (oninput)każda zmiana wartości w trakcie (np. przesuwanie suwaka)suwak zsynchronizowany z polem liczbowym
load, DOMContentLoadedwczytanie strony / zbudowanie drzewa DOMlicznik odwiedzin, wypisanie daty, generowanie bloków
mouseover, mouseoutwejście i wyjście kursoraefekty najechania
keydownwciśnięcie klawiszasterowanie klawiaturą
Obsługa zdarzenia i obiekt zdarzenia
const suwak = document.querySelector("input[type='range']");
suwak.addEventListener("input", function (e) {
    console.log("Nowa wartość:", e.target.value);      // e.target = element, na którym zaszło zdarzenie
});

document.addEventListener("DOMContentLoaded", function () {
    console.log("Strona wczytana");
});

// wykonanie funkcji po załadowaniu strony – dwa równoważne sposoby
window.onload = aktualnaData;
document.addEventListener("DOMContentLoaded", aktualnaData);   // bez nawiasów!
Wybór zdarzenia dla suwaka

Arkusz „wykonywany po zmianie wartości pola zakresu liczbowego (po przesunięciu suwaka)” spełni zarówno oninput (na bieżąco), jak i onchange (po puszczeniu). Wybierz oninput, jeśli wartość ma się zmieniać w trakcie przesuwania.

Sprawdź się — zadanie 1

Czym różnią się zdarzenia input i change na suwaku?

Pokaż przykładową odpowiedź

input zachodzi cały czas podczas przesuwania suwaka, a change dopiero po jego puszczeniu (zatwierdzeniu wartości).

Sprawdź się — zadanie 2

Jak uruchomić funkcję po załadowaniu strony?

Pokaż przykładową odpowiedź

document.addEventListener("DOMContentLoaded", funkcja) lub window.onload = funkcja (bez nawiasów po nazwie funkcji) albo wywołać ją na końcu skryptu umieszczonego na końcu body.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Obsłuż kliknięcie przycisku za pomocą addEventListener.

const przycisk = document.querySelector("#przycisk");
przycisk.("", function () {
    alert("Kliknięto");
});
Ćwiczenie interaktywne — uzupełnij kod

Wywołaj funkcję po zmianie wyboru w liście i po wpisaniu tekstu w polu.

<select ="przelicz()">...</select>
<input type="text" ="szukaj()">
Ćwiczenie interaktywne — popraw kod

Obsługa zdarzenia ma odczytać klikniętą komórkę, ale funkcja nie ma parametru zdarzenia. Popraw funkcję, aby korzystała z event.target.

Ćwiczenie interaktywne — popraw kod

W atrybucie onclick brakuje nawiasów, więc funkcja się nie wykona, a argument tekstowy ma niepoprawne cudzysłowy. Popraw znacznik.

Część B, lekcja 13

Tworzenie elementów DOM i generowanie zawartości

Dwa sposoby generowania zawartości strony ze skryptu: (1) składanie napisu HTML i wstawienie go przez innerHTML, (2) tworzenie węzłów przez createElement. Arkusz czasem wymaga drugiego („Element DOM dla nagłówka…”, „dodaje element do listy”).

createElement i append
const lista = document.querySelector("ul");

const nowy = document.createElement("li");       // utwórz <li>
nowy.textContent = "naleśniki";                  // wypełnij treścią
nowy.classList.add("pozycja");                   // przypisz klasę
lista.append(nowy);                              // dodaj na końcu listy (appendChild też działa)

lista.innerHTML = "";                            // wyczyść całą zawartość listy
document.querySelector("li").remove();           // usuń element
Generowanie przez innerHTML i szablon napisu
const sekcja = document.querySelector("#prawy2");
dane.recepty.forEach(recepta => {
    let leki = "";
    if (recepta.lek1 !== "") leki += `<li>${recepta.lek1}</li>`;
    if (recepta.lek2 !== "") leki += `<li>${recepta.lek2}</li>`;
    if (recepta.lek3 !== "") leki += `<li>${recepta.lek3}</li>`;

    sekcja.innerHTML += `
        <div class="recepta">
            <p>Data wystawienia: ${recepta.data}</p>
            <ol>${leki}</ol>
            <h4>Kod: ${recepta.kod}</h4>
        </div>`;
});
  • Szablon napisu w odwrotnych apostrofach (`...`) może zajmować wiele linii i wstawia wartości przez ${...} – to najwygodniejszy sposób budowania HTML.
  • += na innerHTML dopisuje na końcu; = zastępuje całą zawartość.
  • Klasa elementu z arkusza (np. recepty) musi być dokładnie taka sama jak w poleceniu – CSS już jest do niej przygotowany.
  • Po createElement element nie jest jeszcze na stronie – widać go dopiero po append/appendChild.
Sprawdź się — zadanie 1

Jak dodać element li o treści „pierogi” na koniec listy ul?

Pokaż przykładową odpowiedź

const li = document.createElement("li"); li.textContent = "pierogi"; document.querySelector("ul").append(li);

Sprawdź się — zadanie 2

Jak wyczyścić zawartość listy?

Pokaż przykładową odpowiedź

lista.innerHTML = "";

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Utwórz element listy z tekstem i dołącz go do listy o identyfikatorze lista.

const li = document.("li");
li. = "Gitara";
document.getElementById("lista").(li);
Ćwiczenie interaktywne — uzupełnij kod

Wygeneruj bloki z danych za pomocą szablonu tekstowego i dopisz je do kontenera.

const dane = [{ nazwa: "Rzym" }, { nazwa: "Paryż" }];
const kontener = document.querySelector(".galeria");
dane.forEach(d => {
    kontener.innerHTML  <div class="blok">${d.nazwa}</div>;
});
Ćwiczenie interaktywne — popraw kod

Element jest utworzony, ale nie pojawia się na stronie, bo nie został dołączony do dokumentu. Dodaj brakującą instrukcję.

Ćwiczenie interaktywne — popraw kod

W nazwie metody jest literówka, a obraz nie ma ustawionego źródła. Popraw kod tak, aby powstał obraz z plikiem rower.svg.

Część B, lekcja 14

Formularze w JavaScript: liczby, radio, listy i suwaki

Odczyt różnych pól
// pole liczbowe i suwak
const suwak = document.querySelector("input[type='range']");
const liczba = document.querySelector("input[type='number']");
liczba.value = suwak.value;                              // synchronizacja suwaka z polem

// radio: zaznaczona opcja z grupy o wspólnym name
const wybrany = document.querySelector("input[name='rodzaj']:checked");
console.log(wybrany.value);                               // value zaznaczonego przycisku

// lista rozwijana
const lista = document.querySelector("select");
console.log(lista.value, lista.options[lista.selectedIndex].text);

// pole wyboru
const zgoda = document.querySelector("#zgoda");
console.log(zgoda.checked);                               // true / false

// pole tekstowe
const szukane = document.querySelector("#szukaj").value.trim().toLowerCase();
Odczyt radio bez :checked (pętla)
const opcje = document.querySelectorAll("input[name='rodzaj']");
let wybranyRodzaj = "";
opcje.forEach(opcja => {
    if (opcja.checked) wybranyRodzaj = opcja.value;
});
PoleOdczyt wartościUwagi
text, number, range, datepole.value (napis)liczby zamień przez Number() lub parseInt()
radiodocument.querySelector("input[name='x']:checked").valuejeśli żadne nie jest zaznaczone, wynik to null – zabezpiecz warunkiem
checkboxpole.checkedwartość logiczna
selectlista.valuewartość atrybutu value wybranej opcji
Zawsze wartość z atrybutu value

W grupie radio value musi być ustawione w HTML (<input type="radio" name="rodzaj" value="szosa">), bo to ono trafia do skryptu. Etykieta obok pola nie jest wartością.

Sprawdź się — zadanie 1

Jak odczytać wybraną opcję z grupy przycisków radio o nazwie rodzaj?

Pokaż przykładową odpowiedź

document.querySelector("input[name='rodzaj']:checked").value.

Sprawdź się — zadanie 2

Jak zsynchronizować pole liczbowe z suwakiem?

Pokaż przykładową odpowiedź

W obsłudze zdarzenia input suwaka przypisać poleLiczbowe.value = suwak.value.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Odczytaj liczbę z pola, wybraną opcję z listy i sprawdź pole wyboru.

const ile = (document.getElementById("ile").value);
const kolor = document.getElementById("kolor").;
const zgoda = document.getElementById("zgoda").;
Ćwiczenie interaktywne — uzupełnij kod

Odczytaj zaznaczony przycisk radio z grupy o nazwie rozmiar.

const rozmiar = document.querySelector("input[name='rozmiar']").;
Ćwiczenie interaktywne — popraw kod

Wartość suwaka jest tekstem, więc dodawanie skleja napisy. Zamień ją na liczbę, aby suma była liczbą.

Ćwiczenie interaktywne — popraw kod

Wyświetlana wartość suwaka nie zmienia się podczas przesuwania, bo użyto zdarzenia zmiany zamiast zdarzenia na bieżąco. Popraw nazwę zdarzenia.

Część B, lekcja 15

Liczby, zaokrąglanie i daty

ZadanieZapis
zaokrąglenie do całościMath.round(x); w dół Math.floor(x), w górę Math.ceil(x)
zaokrąglenie do 2 miejsc (jako napis)x.toFixed(2)
zamiana napisu na liczbęNumber("12,5".replace(",", ".")) – przecinek zamień na kropkę
maksimum, minimum, potęga, pierwiastekMath.max(a, b), Math.min(), Math.pow(a, b), Math.sqrt()
liczba losowa całkowita 1–6Math.floor(Math.random() * 6) + 1
Przykład z arkusza: rozmiar ramy roweru
// rozmiar ramy [cale] = wzrost [cm] × współczynnik ÷ 2,54, zaokrąglony do całości
function obliczRozmiarRamy() {
    const wzrost = Number(document.querySelector("input[type='number']").value);
    const rodzaj = document.querySelector("input[name='rodzajRoweru']:checked").value;

    let wspolczynnik = 0.26;                     // górski
    if (rodzaj === "szosa") wspolczynnik = 0.3;
    if (rodzaj === "trekking") wspolczynnik = 0.28;

    const rozmiar = Math.round((wzrost * wspolczynnik) / 2.54);
    document.querySelector("#wynik").textContent = `Zalecany rozmiar ramy to: ${rozmiar} cali`;
}
Data w formacie DD.MM.RRRR
function aktualnaData() {
    const dzis = new Date();
    const dzien = String(dzis.getDate()).padStart(2, "0");        // 5 → "05"
    const miesiac = String(dzis.getMonth() + 1).padStart(2, "0"); // miesiące liczone od 0!
    const rok = dzis.getFullYear();
    document.querySelector("#komorkaDaty").textContent = `${dzien}.${miesiac}.${rok}`;
}
aktualnaData();
Miesiące w obiekcie Date

getMonth() zwraca liczbę od 0 (styczeń) do 11 (grudzień), więc do wyświetlenia trzeba dodać 1. getDay() zwraca dzień tygodnia (0 = niedziela), a dzień miesiąca daje getDate().

Sprawdź się — zadanie 1

Jak zapisać w JavaScript dzisiejszą datę jako 07.03.2026?

Pokaż przykładową odpowiedź

Pobrać new Date(), dzień i miesiąc (getMonth() + 1) uzupełnić zerem przez String(x).padStart(2, "0") i złożyć `${dzien}.${miesiac}.${rok}`.

Sprawdź się — zadanie 2

Jak zaokrąglić wynik 61,6 do liczby całkowitej?

Pokaż przykładową odpowiedź

Math.round(61.6) daje 62.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Zaokrąglij liczbę do całości i wyświetl ją z dwoma miejscami po przecinku.

console.log(Math.(3.6));
console.log((2.5).(2));
Ćwiczenie interaktywne — uzupełnij kod

Pobierz bieżącą datę, rok i numer miesiąca (miesiące liczone są od zera).

const dzis = new ();
const rok = dzis.();
const miesiac = dzis.getMonth() ;
Ćwiczenie interaktywne — popraw kod

Liczba dni między datami jest błędna, bo różnica jest wyrażona w milisekundach. Przelicz ją na dni.

Ćwiczenie interaktywne — popraw kod

Wynik ma mieć dwa miejsca po przecinku, ale funkcja jest wywołana na całej wartości jak zwykła funkcja. Popraw zapis.

Część B, lekcja 16

localStorage, sessionStorage i alerty

Licznik odwiedzin w localStorage
function licznik() {
    let liczba = localStorage.getItem("odwiedziny");      // napis lub null
    liczba = liczba === null ? 0 : parseInt(liczba);
    liczba++;
    localStorage.setItem("odwiedziny", liczba);

    const stopka = document.querySelector("#licznikWejsc");
    if (stopka) stopka.textContent = `Liczba wejść na stronę: ${liczba}`;
}
document.addEventListener("DOMContentLoaded", licznik);   // bez nawiasów!
MechanizmCzas życiaZasięg
localStoragebez ograniczenia czasu (do ręcznego usunięcia)wszystkie karty tej samej witryny (domena + protokół + port)
sessionStoragedo zamknięcia kartytylko dana karta
ciasteczka (document.cookie)ustawiany datą ważnościwysyłane do serwera z każdym żądaniem
  • Metody: setItem(klucz, wartość), getItem(klucz), removeItem(klucz), clear(). Wartości są zawsze napisami, więc liczbę zamieniasz przez parseInt/Number.
  • Obiekty i tablice zapisujesz przez JSON.stringify, odczytujesz przez JSON.parse.
  • Zawartość podglądniesz w DevTools: Application → Local Storage (przydatne do zerowania licznika podczas testów).
  • Okna dialogowe: alert("Tekst") – komunikat, confirm("Na pewno?") – zwraca true/false, prompt("Podaj imię") – zwraca wpisany napis lub null.
Pierwsze wejście

Przy pierwszym uruchomieniu getItem zwraca null; parseInt(null) to NaN i licznik się zepsuje. Zawsze obsłuż przypadek braku wartości (jak w przykładzie).

Sprawdź się — zadanie 1

Co zwróci localStorage.getItem("klucz"), gdy takiego klucza nie zapisano?

Pokaż przykładową odpowiedź

Wartość null.

Sprawdź się — zadanie 2

Jak zapisać w localStorage tablicę obiektów?

Pokaż przykładową odpowiedź

localStorage.setItem("lista", JSON.stringify(tablica)), a odczytać JSON.parse(localStorage.getItem("lista")).

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Zapisz wartość w localStorage, odczytaj ją i usuń.

localStorage.("imie", "Anna");
const imie = localStorage.("imie");
localStorage.("imie");
Ćwiczenie interaktywne — uzupełnij kod

Zapisz w localStorage tablicę (jako tekst JSON) i odczytaj ją z powrotem.

localStorage.setItem("koszyk", JSON.(koszyk));
const koszyk2 = JSON.(localStorage.getItem("koszyk"));
Ćwiczenie interaktywne — popraw kod

Do localStorage można zapisać tylko tekst, więc tablica jest zapisana jako „[object Object]”. Zamień obiekt na tekst JSON.

Ćwiczenie interaktywne — uzupełnij kod

Wyświetl komunikat i zapytaj użytkownika o potwierdzenie.

("Zamówienie przyjęte");
if (("Czy na pewno usunąć?")) {
    console.log("usunięto");
}

Zadanie praktyczne

Mini-aplikacja: kalkulator zamówienia

Szacowany czas: 45 minZakres: Lekcje 8–14Forma: pliki zamowienie.html, styl.css, main.js

Zadanie

Wykonaj stronę „Zamów pizzę”. Układ i style przygotuj samodzielnie, a skrypty napisz według wymagań.

Założenia

  • Formularz: pole number „Liczba osób” (1–10) z powiązanym suwakiem range (1–10), grupa radio „Rozmiar” (mała 20 zł, średnia 28 zł, duża 36 zł) i lista rozwijana „Dodatek” (brak 0 zł, ser 4 zł, szynka 6 zł).
  • Skrypt 1 (po przesunięciu suwaka): wpisuje wartość suwaka do pola liczbowego. Skrypt 2 (po wpisaniu liczby w polu): ustawia suwak na tę wartość.
  • Skrypt 3 (po kliknięciu „Oblicz”): koszt = (cena rozmiaru + cena dodatku) × liczba osób; wynik w akapicie w formacie „Do zapłaty: 64.00 zł” (dwa miejsca po przecinku). Jeśli nie wybrano rozmiaru – wypisz „Wybierz rozmiar”.
  • Skrypt 4 (po załadowaniu strony): w stopce wypisuje datę w formacie DD.MM.RRRR oraz zwiększa i pokazuje licznik wizyt zapisany w localStorage.
  • Wszystkie funkcje mają znaczące nazwy po polsku; nie wolno zmieniać nazw klas i identyfikatorów podanych w projekcie.

Ocenie podlegać będzie

  • poprawna synchronizacja suwaka i pola,
  • poprawny odczyt radio i listy oraz obliczenia,
  • formatowanie wyniku i obsługa braku wyboru,
  • data i licznik w localStorage,
  • czytelność kodu.
Wskazówki
  • Pole number i suwak: użyj zdarzenia oninput w obu elementach.
  • Cena dodatku: Number(select.value) – ustaw value w opcjach.
  • Lekcje 12–14.

Część C

Wzorce zadań egzaminacyjnych

Sześć kompletnych wzorców (galeria z oknem, przełączanie sekcji i karuzela, lista zamówienia, generowanie z danych, kalkulator, plansza gry) oraz lista kontrolna i debugowanie.

Część C, lekcja 17

Wzorzec 1: galeria z podmianą obrazu i oknem powiększenia

Sytuacja z arkusza: karta produktu ma obraz główny i trzy miniatury. Kliknięcie miniatury podmienia obraz główny; kliknięcie obrazu głównego otwiera okno z jego powiększeniem; kliknięcie znaku × zamyka okno. Okno ma być ukryte stylem CSS, a skrypt zmienia sposób jego wyświetlania. Pliki do ćwiczenia: js-galeria.zip (obrazy rower1–3).

index.html
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Karta produktu</title>
    <link rel="stylesheet" href="styl.css">
    <script src="main.js" defer></script>
</head>
<body>
    <header><h1>Rower miejski</h1></header>
    <main>
        <section>
            <img class="obraz" src="img/rower1.svg" alt="rower" onclick="otworzOkno()">
            <div>
                <img class="miniatury" src="img/rower1.svg" alt="miniatura" onclick="podmienObraz('rower1.svg')">
                <img class="miniatury" src="img/rower2.svg" alt="miniatura" onclick="podmienObraz('rower2.svg')">
                <img class="miniatury" src="img/rower3.svg" alt="miniatura" onclick="podmienObraz('rower3.svg')">
            </div>
        </section>
        <article>
            <h2>Rower miejski Eco</h2>
            <p>Lekki rower z koszykiem i błotnikami.</p>
        </article>
    </main>

    <div class="okno">
        <span class="zamknij" onclick="zamknijOkno()">&times;</span>
        <img class="obrazOkno" alt="powiększenie">
    </div>
</body>
</html>
styl.css (fragment dotyczący okna)
.obraz { width: 40%; cursor: zoom-in; }
.miniatury { width: 15%; cursor: pointer; }

.okno {
    display: none;                          /* ukryte na starcie – skrypt zmieni na block */
    position: fixed;                        /* względem okna przeglądarki */
    top: 0;
    left: 0;
    width: 80%;
    height: 100%;
    z-index: 10;                            /* zawsze na wierzchu */
    background-color: rgba(0, 0, 0, 0.7);   /* czarne tło z przezroczystością */
}
.obrazOkno { display: block; margin: 40px auto; max-width: 80%; }   /* blokowy, środek */
.zamknij {
    position: absolute;                     /* względem pierwszego pozycjonowanego rodzica (.okno) */
    top: 15px;
    right: 35px;
    font-size: 40px;
    font-weight: bold;
    color: beige;
}
.zamknij:hover { cursor: pointer; }
main.js
function podmienObraz(nazwaPliku) {
    const obrazGlowny = document.querySelector(".obraz");
    obrazGlowny.src = `img/${nazwaPliku}`;
}

function otworzOkno() {
    const obrazGlowny = document.querySelector(".obraz");
    const okno = document.querySelector(".okno");
    const obrazOkno = document.querySelector(".obrazOkno");
    okno.style.display = "block";            // zmiana sposobu wyświetlania bloku okna na blokowy
    obrazOkno.src = obrazGlowny.src;         // źródło obrazu z okna = źródło obrazu głównego
}

function zamknijOkno() {
    document.querySelector(".okno").style.display = "none";
}

Dlaczego to działa

  • Obraz główny i miniatury mają różne klasy (obraz, miniatury), więc querySelector(".obraz") trafia zawsze w obraz główny.
  • obrazGlowny.src zwraca pełny adres (np. http://localhost/img/rower2.svg) – można go bezpośrednio przypisać do drugiego obrazu.
  • Ukrycie okna w CSS (display: none) i pokazanie w JS (display = "block") to dokładnie to, o co prosi arkusz („zmiana sposobu wyświetlania bloku okna”).
  • Krzyżyk &times; to znak ×, a jego położenie względem okna zapewnia position: absolute.
Typowe błędy punktowane ujemnie

style.display = "visible" (taka wartość nie istnieje – poprawnie block), brak średnika lub cudzysłowu w ścieżce img/${...}, zmiana nazw klas z arkusza, próba użycia id tam, gdzie arkusz wymaga klasy.

Sprawdź się — zadanie 1

Którą właściwością CSS ukryjesz okno początkowo, aby skrypt mógł je pokazać?

Pokaż przykładową odpowiedź

display: none; w stylach klasy okna; skrypt zmieni na block.

Sprawdź się — zadanie 2

Dlaczego źródło obrazu głównego można przypisać obrazowi z okna bez dopisywania ścieżki?

Pokaż przykładową odpowiedź

Bo właściwość src elementu img zwraca pełny adres obrazu, który jest poprawnym źródłem dla każdego innego obrazu.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Podmień obraz główny po kliknięciu miniatury (nazwa pliku jest argumentem).

function podmienObraz(plik) {
    document.querySelector(".obraz"). = ;
}
Ćwiczenie interaktywne — uzupełnij kod

Otwórz okno powiększenia, a po kliknięciu przycisku zamknięcia ukryj je.

function otworz() {
    document.querySelector(".okno").style.display = "";
}
function zamknij() {
    document.querySelector(".okno").style.display = "";
}
document.querySelector(".zamknij"). = zamknij;
Ćwiczenie interaktywne — popraw kod

Wszystkie miniatury mają reagować na kliknięcie, ale po wczytaniu strony obraz jest podmieniany od razu, bo funkcja jest wywoływana od razu zamiast zostać przypisana jako obsługa zdarzenia. Popraw kod.

Ćwiczenie interaktywne — popraw kod

Powiększony obraz ma pokazać opis z atrybutu alt kliknętego obrazka, ale kod odczytuje go z niewłaściwego obiektu. Popraw odwołanie.

Część C, lekcja 18

Wzorzec 2: przełączanie sekcji formularza i karuzela zdjęć

Sytuacja z arkusza: strona rezerwacji ma dwa przyciski („Uczestnik” i „Rezerwacja”) przełączające, która część formularza jest aktywna, oraz zmieniające kolor przycisków. Obok jest przeglądarka zdjęć z dwiema strzałkami: kolejne i poprzednie miejsce, z zawinięciem na końcach. Obrazy do ćwiczenia: js-wycieczki.zip.

index.html (fragment)
<nav>
    <button id="uczestnikBtn" onclick="zmienSekcje('uczestnik')">Uczestnik</button>
    <button id="rezerwacjaBtn" onclick="zmienSekcje('rezerwacja')">Rezerwacja</button>
</nav>

<section id="sekcjaUczestnik">
    <input type="text" id="imie" placeholder="Imię">
    <input type="text" id="nazwisko" placeholder="Nazwisko">
</section>
<section id="sekcjaRezerwacja">
    <input type="number" id="liczbaOsob" value="1" min="1">
    <select id="miejsceWylotu"><option>Warszawa</option><option>Kraków</option></select>
    <label><input type="radio" name="wyzywienie" value="bez"> bez</label>
    <label><input type="radio" name="wyzywienie" value="pelne"> pełne</label>
</section>

<aside>
    <img id="zdjecieMiejsca" src="img/1.svg" alt="zdjęcie miejsca">
    <p id="miejsceWycieczki">Barcelona</p>
    <button onclick="poprzedniaWycieczka()">&#8592;</button>
    <button onclick="nastepnaWycieczka()">&#8594;</button>
</aside>
main.js
/* ---- przełączanie aktywnej części formularza ---- */
function zmienSekcje(wybrana) {
    const uczestnik = wybrana === "uczestnik";
    document.querySelectorAll("#sekcjaUczestnik input").forEach(p => p.disabled = !uczestnik);
    document.querySelectorAll("#sekcjaRezerwacja input, #sekcjaRezerwacja select").forEach(p => p.disabled = uczestnik);

    document.querySelector("#uczestnikBtn").style.backgroundColor = uczestnik ? "dodgerblue" : "skyblue";
    document.querySelector("#rezerwacjaBtn").style.backgroundColor = uczestnik ? "skyblue" : "dodgerblue";
}
zmienSekcje("uczestnik");                       // stan początkowy ustawiony w skrypcie

/* ---- przeglądarka zdjęć z zawinięciem ---- */
const wycieczki = [
    { obraz: "img/1.svg", miejsce: "Barcelona" },
    { obraz: "img/2.svg", miejsce: "Rzym" },
    { obraz: "img/3.svg", miejsce: "Londyn" }
];
let numerWycieczki = 0;

function pokazWycieczke() {
    document.querySelector("#zdjecieMiejsca").src = wycieczki[numerWycieczki].obraz;
    document.querySelector("#miejsceWycieczki").textContent = wycieczki[numerWycieczki].miejsce;
}

function nastepnaWycieczka() {
    numerWycieczki++;
    if (numerWycieczki >= wycieczki.length) numerWycieczki = 0;       // po ostatniej – pierwsza
    pokazWycieczke();
}

function poprzedniaWycieczka() {
    numerWycieczki--;
    if (numerWycieczki < 0) numerWycieczki = wycieczki.length - 1;    // przed pierwszą – ostatnia
    pokazWycieczke();
}
PułapkaOpis
indeks poza zakresembez zawinięcia po trzecim kliknięciu wycieczki[3] jest undefined i skrypt zgłasza błąd
pole disabled a kolorustawiasz osobno disabled i style.backgroundColor; arkusz wymaga obu efektów
różna liczba elementówpętlę po querySelectorAll zapisuj przez forEach, a nie przez indeksy na sztywno
kolejność wycieczekarkusz podaje kolejność wstecz (Barcelona → Londyn → Rzym) – sprawdź krok po kroku, klikając strzałkę kilka razy
Sposób na zawinięcie jednym wyrażeniem

Zamiast dwóch if możesz użyć reszty z dzielenia: numer = (numer + krok + ile) % ile, gdzie krok to +1 lub −1, a ile to długość tablicy.

Sprawdź się — zadanie 1

Jak zapewnić, że po ostatniej wycieczce wyświetli się pierwsza?

Pokaż przykładową odpowiedź

Po zwiększeniu numeru sprawdzić if (numer >= wycieczki.length) numer = 0; lub użyć numer = (numer + 1) % wycieczki.length.

Sprawdź się — zadanie 2

Jak zablokować wszystkie pola w jednej sekcji formularza?

Pokaż przykładową odpowiedź

Pobrać pola przez querySelectorAll("#sekcja input") i dla każdego ustawić disabled = true (forEach).

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Pokaż tylko wybraną sekcję formularza: ukryj wszystkie, pokaż jedną.

function zmienSekcje(id) {
    document.querySelectorAll(".sekcja").forEach(s => s.style.display = "");
    document.getElementById(id).style.display = "";
}
Ćwiczenie interaktywne — uzupełnij kod

Karuzela: przejdź do następnego zdjęcia, a po ostatnim wróć do pierwszego.

let numer = 0;
function dalej() {
    numer = (numer + 1)  zdjecia.;
    obraz.src = zdjecia[numer];
}
Ćwiczenie interaktywne — popraw kod

Przycisk „wstecz” w karuzeli powoduje błąd po przejściu przed pierwsze zdjęcie (indeks −1). Popraw kod tak, aby po pierwszym zdjęciu wyświetlało się ostatnie.

Ćwiczenie interaktywne — popraw kod

Sekcja formularza ma pozostać ukryta, dopóki nie zostanie wybrana, ale zapis stylu jest błędny. Popraw kod.

Część C, lekcja 19

Wzorzec 3: lista zamówienia (createElement, alert, czyszczenie)

Sytuacja z arkusza: strona restauracji ma bloki z potrawami. Kliknięcie bloku dodaje nazwę potrawy do listy zamówienia, przycisk „Wyczyść” czyści listę, a „Zatwierdź” wyświetla komunikat i czyści listę. Obrazy: js-zamowienia.zip.

index.html (fragment)
<main>
    <section class="menu">
        <div class="potrawa" onclick="dodajDoZamowienia('naleśniki')">
            <img src="img/nalesniki.svg" alt="naleśniki"><h3>Naleśniki</h3>
        </div>
        <div class="potrawa" onclick="dodajDoZamowienia('pierogi')">
            <img src="img/pierogi.svg" alt="pierogi"><h3>Pierogi</h3>
        </div>
        <div class="potrawa" onclick="dodajDoZamowienia('zupa dnia')">
            <img src="img/zupa.svg" alt="zupa"><h3>Zupa dnia</h3>
        </div>
    </section>
    <section class="zamowienie">
        <h2>Twoje zamówienie</h2>
        <ul></ul>
        <button onclick="wyczyscZamowienie()">Wyczyść</button>
        <button onclick="zatwierdzZamowienie()">Zatwierdź</button>
    </section>
</main>
main.js
function dodajDoZamowienia(nazwaPotrawy) {
    const lista = document.querySelector(".zamowienie ul");
    const pozycja = document.createElement("li");
    pozycja.textContent = nazwaPotrawy;
    lista.append(pozycja);
}

function wyczyscZamowienie() {
    document.querySelector(".zamowienie ul").innerHTML = "";
}

function zatwierdzZamowienie() {
    const lista = document.querySelector(".zamowienie ul");
    if (lista.children.length === 0) {                 // opcjonalne zabezpieczenie: pusta lista
        alert("Zamówienie jest puste");
        return;
    }
    alert("Zamówienie zostało przekazane do realizacji");
    lista.innerHTML = "";
}
  • Tekst alertu wpisz dokładnie jak w arkuszu (łącznie z polskimi znakami i bez dodatkowych znaków).
  • Selektor ".zamowienie ul" jest bezpieczniejszy niż samo "ul", jeśli na stronie jest jeszcze inna lista (np. menu).
  • lista.children.length to liczba elementów potomnych – przydaje się do sprawdzenia, czy lista jest pusta.
  • Rozszerzenie: zliczanie powtórzeń (kliknięto „pierogi” 2×) lub przycisk usuwania pojedynczej pozycji.
Sprawdź się — zadanie 1

Jak dodać element li z napisem do istniejącej listy ul?

Pokaż przykładową odpowiedź

const li = document.createElement("li"); li.textContent = tekst; lista.append(li);

Sprawdź się — zadanie 2

Jak sprawdzić, ile pozycji ma lista?

Pokaż przykładową odpowiedź

lista.children.length lub lista.querySelectorAll("li").length.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Dodaj do listy zamówienia nowy element z nazwą produktu.

function dodaj(nazwa) {
    const li = document.createElement("li");
    li.textContent = nazwa;
    document.getElementById("zamowienie").(li);
}
Ćwiczenie interaktywne — uzupełnij kod

Wyczyść listę zamówienia i pokaż komunikat.

function wyczysc() {
    document.getElementById("zamowienie").innerHTML = ;
    ("Lista wyczyszczona");
}
Ćwiczenie interaktywne — popraw kod

Przed złożeniem zamówienia trzeba sprawdzić, czy lista nie jest pusta. Warunek w kodzie jest odwrócony. Popraw go.

Ćwiczenie interaktywne — popraw kod

Suma zamówienia powinna rosnąć o cenę produktu, ale po każdym dodaniu jest nadpisywana. Popraw kod.

Część C, lekcja 20

Wzorzec 4: generowanie bloków z danych i wyszukiwarka

Sytuacja z arkusza (recepty): w pliku jest struktura danych pacjenta. Skrypt ma wygenerować tyle bloków, ile jest recept; w każdym: data, lista numerowana leków (pomijamy puste) i nagłówek z kodem. Sytuacja z arkusza (atlas): dwie tablice (nazwy i opisy) – kliknięcie obrazu lub wpisanie nazwy generuje nagłówek i opis w bloku głównym.

Generowanie bloków z JSON
const pacjent = {
    imie: "Agnieszka",
    recepty: [
        { data: "8.03.2025",  kod: "1220", lek1: "Witamina C", lek2: "Potas",     lek3: "Syrop prawoślazowy" },
        { data: "23.04.2025", kod: "4634", lek1: "APAP",       lek2: "Witamina B", lek3: "" },
        { data: "13.05.2025", kod: "2913", lek1: "Melatonina", lek2: "",           lek3: "" }
    ]
};

const sekcja = document.querySelector("#prawy2");

pacjent.recepty.forEach(recepta => {
    let leki = "";
    if (recepta.lek1 !== "") leki += `<li>${recepta.lek1}</li>`;
    if (recepta.lek2 !== "") leki += `<li>${recepta.lek2}</li>`;
    if (recepta.lek3 !== "") leki += `<li>${recepta.lek3}</li>`;

    sekcja.innerHTML += `
        <div class="recepty">
            <p>Data wystawienia: ${recepta.data}</p>
            <ol>${leki}</ol>
            <h4>Kod: ${recepta.kod}</h4>
        </div>`;
});
Atlas: dwie tablice, klik i wyszukiwarka
const drzewa = ["buk", "lipa", "wierzba", "dąb"];
const opisy = [
    "Duże drzewo liściaste z gładką, szarą korą.",
    "Drzewo o sercowatych liściach i pachnących kwiatach.",
    "Rośnie nad wodą, ma długie, zwisające gałęzie.",
    "Majestatyczne, długowieczne drzewo, owocuje żołędziami."
];

function wybierz(indeks) {                           // wywoływana z onclick="wybierz(0)" na obrazach
    const blok = document.querySelector("main");
    blok.innerHTML = "";                             // usuń zawartość bloku głównego
    const naglowek = document.createElement("h2");
    naglowek.textContent = drzewa[indeks];
    const akapit = document.createElement("p");
    akapit.classList.add("opis");
    akapit.textContent = opisy[indeks];
    blok.append(naglowek, akapit);                   // append przyjmuje kilka elementów
}

function szukaj() {                                  // onclick="szukaj()" na przycisku „Szukaj”
    const wpisane = document.querySelector("#szukane").value.trim().toLowerCase();
    if (drzewa.includes(wpisane)) {
        wybierz(drzewa.indexOf(wpisane));
    } else {
        document.querySelector("main").innerHTML =
            "<p>Drzewa, o którym chcesz znaleźć informacje, nie ma w naszym Atlasie drzew.</p>";
    }
}
Wymaganie arkuszaJak je spełnić
„tyle bloków, ile elementów tablicy”pętla forEach po tablicy, nigdy po stałej liczbie
„puste wpisy pomijamy”warunek if (pole !== "") przed dodaniem <li>
„przypisana klasa”nazwa klasy dokładnie jak w arkuszu (recepty, opis)
„usuwa zawartość bloku głównego”blok.innerHTML = "" przed dodaniem nowych elementów
„Element DOM dla nagłówka…”createElement("h2") i append (nie sam napis HTML)
Wyszukiwarka a wielkość liter

Gdy arkusz nie mówi inaczej, porównuj nazwy po trim().toLowerCase() – użytkownik może wpisać „Buk ” albo „BUK”. Tablica nazw musi wtedy zawierać tylko małe litery.

Sprawdź się — zadanie 1

Jak pominąć puste pola lek2 i lek3 przy generowaniu listy leków?

Pokaż przykładową odpowiedź

Przed dodaniem elementu sprawdzić warunek if (recepta.lek2 !== "") i tylko wtedy dopisać <li>.

Sprawdź się — zadanie 2

Jak znaleźć opis drzewa o nazwie wpisanej w polu, korzystając z dwóch tablic?

Pokaż przykładową odpowiedź

Znaleźć indeks nazwy w tablicy nazw (indexOf), a opis odczytać z tablicy opisów pod tym samym indeksem.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Wygeneruj blok HTML dla każdego elementu tablicy danych.

dane.(el => {
    kontener.innerHTML += `<div class="blok"><h3></h3><p>${el.cena} zł</p></div>`;
});
Ćwiczenie interaktywne — uzupełnij kod

Wyszukiwarka: pozostaw tylko elementy, których nazwa zawiera wpisany tekst (bez rozróżniania wielkości liter).

const fraza = pole.value.();
const wynik = dane.(el => el.nazwa.toLowerCase().(fraza));
Ćwiczenie interaktywne — popraw kod

Przed ponownym wygenerowaniem bloków trzeba wyczyścić kontener, bo bloki się dublują. Dodaj brakującą instrukcję na początku funkcji.

Ćwiczenie interaktywne — popraw kod

W szablonie tekstowym użyto zwykłych cudzysłowów, więc wartość zmiennej nie jest wstawiana. Popraw zapis.

Część C, lekcja 21

Wzorzec 5: kalkulator z suwakiem, radio i datą

Sytuacja z arkusza: strona salonu rowerowego ma suwak wzrostu zsynchronizowany z polem liczbowym, trzy opcje typu roweru i przycisk „Sprawdź”, który wylicza zalecany rozmiar ramy; po załadowaniu strony w komórce tabeli ma się pojawić dzisiejsza data.

index.html (fragment)
<section>
    <h3>Dobierz ramę</h3>
    <input type="range" min="140" max="210" value="170" oninput="aktualizujPole()">
    <input type="number" min="140" max="210" value="170" oninput="aktualizujSuwak()">
    <p>
        <label><input type="radio" name="rodzajRoweru" value="gorski" checked> górski z kołami 29"</label>
        <label><input type="radio" name="rodzajRoweru" value="szosa"> szosa</label>
        <label><input type="radio" name="rodzajRoweru" value="trekking"> trekking</label>
    </p>
    <button onclick="obliczRozmiarRamy()">Sprawdź</button>
    <p id="wynik"></p>
</section>
<table><tr><td>Dzisiejsza data:</td><td id="komorkaDaty"></td></tr></table>
main.js
function aktualizujPole() {                       // suwak → pole
    const suwak = document.querySelector("input[type='range']");
    document.querySelector("input[type='number']").value = suwak.value;
}
function aktualizujSuwak() {                      // pole → suwak (rozszerzenie)
    const pole = document.querySelector("input[type='number']");
    document.querySelector("input[type='range']").value = pole.value;
}

function obliczRozmiarRamy() {
    const wzrost = Number(document.querySelector("input[type='number']").value);
    const rodzaj = document.querySelector("input[name='rodzajRoweru']:checked").value;

    let wspolczynnik = 0.26;
    if (rodzaj === "szosa") wspolczynnik = 0.3;
    if (rodzaj === "trekking") wspolczynnik = 0.28;

    const rozmiar = Math.round((wzrost * wspolczynnik) / 2.54);
    document.querySelector("#wynik").textContent = `Zalecany rozmiar ramy to: ${rozmiar} cali`;
}

function aktualnaData() {
    const dzis = new Date();
    const dzien = String(dzis.getDate()).padStart(2, "0");
    const miesiac = String(dzis.getMonth() + 1).padStart(2, "0");
    document.querySelector("#komorkaDaty").textContent = `${dzien}.${miesiac}.${dzis.getFullYear()}`;
}
aktualnaData();                                    // wywołanie przy ładowaniu (skrypt z defer)
Kontrola obliczeń
170 cm, szosa:      170 × 0,3  = 51    → 51 / 2,54 = 20,08  → 20 cali
170 cm, górski:     170 × 0,26 = 44,2  → 44,2 / 2,54 = 17,40 → 17 cali
170 cm, trekking:   170 × 0,28 = 47,6  → 47,6 / 2,54 = 18,74 → 19 cali
Brak zaznaczonego radio

Jeśli żadne radio nie jest zaznaczone (brak checked), querySelector("...:checked") zwraca null, a .value zgłasza błąd. Na egzaminie ustaw checked na pierwszej opcji w HTML albo dodaj warunek if (wybrany).

Sprawdź się — zadanie 1

Co wyświetli skrypt dla wzrostu 180 cm i roweru trekkingowego?

Pokaż przykładową odpowiedź

180 × 0,28 = 50,4; 50,4 / 2,54 ≈ 19,84, po zaokrągleniu 20, czyli „Zalecany rozmiar ramy to: 20 cali”.

Sprawdź się — zadanie 2

Dlaczego w obliczeniach trzeba użyć Number() przy odczycie z pola?

Pokaż przykładową odpowiedź

Bo value jest napisem; bez konwersji działanie wzrost * 0.26 zadziała (JavaScript zamieni napis), ale np. dodawanie skleiłoby napisy, więc dla bezpieczeństwa zawsze konwertuj.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Kalkulator ceny: pomnóż liczbę dni przez cenę za dzień i dodaj opłatę zależną od zaznaczonego przycisku radio.

const dni = Number(document.getElementById("dni").value);
const oplata = Number(document.querySelector("input[name='typ']").value);
const razem = dni  120  oplata;
document.getElementById("wynik").textContent = razem.(2) + " zł";
Ćwiczenie interaktywne — popraw kod

Liczba dni pobytu powinna wynikać z różnicy dat, ale zamiast dni wyświetla się liczba milisekund. Popraw obliczenie.

Ćwiczenie interaktywne — uzupełnij kod

Aktualizuj etykietę przy przesuwaniu suwaka i przelicz wynik.

suwak.addEventListener("", () => {
    etykieta.textContent = suwak.;
    przelicz();
});
Ćwiczenie interaktywne — popraw kod

Cena jest wyświetlana z wieloma miejscami po przecinku. Zaokrąglij ją do dwóch miejsc.

Część C, lekcja 22

Wzorzec 6: plansza do gry (stan gry i zdarzenia)

Sytuacja z arkusza: plansza 3×3 w tabeli, w każdej komórce obraz „puste pole”. Gracze (kółko i krzyżyk) klikają na zmianę puste pole. Po ruchu kółka widoczny jest napis „Gra krzyżyk”, po ruchu krzyżyka „Gra kółko”. Kliknięcie zajętego pola nic nie robi. Obrazy: js-gra.zip.

index.html (fragment)
<section id="lewa"><h3>Gra kółko</h3></section>
<table>
    <tr>
        <td><img src="img/nic.svg" alt="pole" onclick="zaznaczPole(this)"></td>
        <td><img src="img/nic.svg" alt="pole" onclick="zaznaczPole(this)"></td>
        <td><img src="img/nic.svg" alt="pole" onclick="zaznaczPole(this)"></td>
    </tr>
    <!-- wiersze 2 i 3 analogicznie -->
</table>
<section id="prawa"><h3>Gra krzyżyk</h3></section>
main.js
let gracz = "kolko";                          // stan początkowy: zaczyna kółko

const sekcjaLewa = document.querySelector("#lewa");
const sekcjaPrawa = document.querySelector("#prawa");
sekcjaPrawa.style.visibility = "hidden";       // początkowo widoczny jest napis „Gra kółko”

function zaznaczPole(pole) {
    if (!pole.src.includes("nic.svg")) return;     // pole zajęte → brak akcji

    if (gracz === "kolko") {
        pole.src = "img/o.svg";
        sekcjaLewa.style.visibility = "hidden";
        sekcjaPrawa.style.visibility = "visible";
        gracz = "krzyzyk";
    } else {
        pole.src = "img/x.svg";
        sekcjaLewa.style.visibility = "visible";
        sekcjaPrawa.style.visibility = "hidden";
        gracz = "kolko";
    }
}
  • Stan gry (gracz) to zmienna poza funkcją – inaczej jej wartość zniknęłaby po każdym kliknięciu.
  • onclick="zaznaczPole(this)" przekazuje klikniętą komórkę, więc funkcja nie musi jej wyszukiwać.
  • pole.src.includes("nic.svg") to sprawdzenie, czy pole jest jeszcze puste (src zawiera pełny adres, więc porównanie === z samą nazwą pliku by nie zadziałało).
  • Instrukcja return przerywa funkcję – brak akcji dla zajętego pola.

Rozszerzenie: wykrywanie wygranej

Sprawdzenie wygranej na planszy 3×3
const wygrywajace = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];

function czyWygral(symbol) {                        // symbol: "o.svg" lub "x.svg"
    const pola = document.querySelectorAll("table img");
    return wygrywajace.some(uklad => uklad.every(i => pola[i].src.includes(symbol)));
}
// po ruchu: if (czyWygral("o.svg")) alert("Wygrało kółko!");
Sprawdź się — zadanie 1

Dlaczego zmienną gracz deklarujemy poza funkcją?

Pokaż przykładową odpowiedź

Aby jej wartość zachowała się między kolejnymi wywołaniami funkcji; zmienna lokalna byłaby tworzona od nowa przy każdym kliknięciu.

Sprawdź się — zadanie 2

Jak sprawdzić, czy kliknięte pole jest puste?

Pokaż przykładową odpowiedź

Sprawdzić, czy pole.src zawiera nazwę pliku z obrazem pustego pola (includes("nic.svg")).

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Plansza: obsłuż kliknięcie komórki, przekazując w HTML kliknięty element.

<td ="zaznacz()"></td>
Ćwiczenie interaktywne — uzupełnij kod

Zmień stan klikniętej komórki i pilnuj, aby nie dało się jej kliknąć drugi raz.

function zaznacz(komorka) {
    if (komorka.classList.contains("zajete")) ;
    komorka.classList.("zajete");
    komorka.textContent = gracz;
}
Ćwiczenie interaktywne — popraw kod

Zmiana gracza po każdym ruchu nie działa, bo użyto przypisania w warunku. Popraw kod.

Ćwiczenie interaktywne — popraw kod

Licznik ruchów ma rosnąć po każdym kliknięciu, ale po wywołaniu funkcji zmienna jest lokalna i się nie zachowuje. Przenieś deklarację zmiennej poza funkcję.

Część C, lekcja 23

Debugowanie i lista kontrolna skryptów JavaScript

ObjawNajczęstsza przyczynaNaprawa
nic się nie dzieje po kliknięciufunkcja nie jest podłączona (literówka w onclick) lub skrypt się nie wczytał (zła ścieżka)otwórz Console i Network (F12); sprawdź nazwę pliku i funkcji
Cannot read properties of nullquerySelector nie znalazł elementu (zły selektor, skrypt w head bez defer)popraw selektor, dodaj defer, sprawdź console.log(element)
X is not definedliterówka w nazwie lub funkcja w innym zakresiesprawdź wielkość liter: zamknijOkno ≠ zamknijokno
Unexpected tokenbrak nawiasu, przecinka, cudzysłowuprzeczytaj linię z konsoli
wynik „NaN”pusty napis lub tekst zamieniany na liczbęNumber(pole.value) i sprawdź, czy pole nie jest puste
wynik „1605” zamiast 165dodawanie napisówzamień na liczby przed działaniem
zmiana stylu nie działazapis style.background-color zamiast backgroundColorcamelCase w style
skrypt działa tylko razzmienna stanu utworzona wewnątrz funkcjiprzenieś zmienną poza funkcję
lista rośnie przy każdym kliknięciuużyto += bez czyszczeniawyczyść innerHTML = "" przed generowaniem

Lista kontrolna przed oddaniem pracy

  • plik main.js jest w folderze z numerem zdającego i podłączony do strony (sprawdź w karcie Network, że ładuje się bez błędu 404),
  • każdy wymagany skrypt wykonałeś w przeglądarce: kliknij, wpisz, zmień wartości, porównaj z ilustracjami z arkusza,
  • teksty komunikatów, nazwy klas i identyfikatory są takie jak w arkuszu,
  • w konsoli (F12) nie ma czerwonych błędów po załadowaniu i po użyciu funkcji,
  • nazwy zmiennych i funkcji są znaczące, kod ma wcięcia, brak zbędnych console.log,
  • zapisałeś wszystkie pliki (Ctrl+S) i zapisałeś nazwę przeglądarki w pliku przegladarka.txt.
Zasada pracy

Pisz skrypt małymi krokami: najpierw funkcja, która tylko wypisuje coś w konsoli, potem prosta zmiana na stronie, potem pełne wymaganie. Po każdym kroku odśwież stronę (Ctrl+F5) i sprawdź konsolę. Błąd znaleziony po 3 liniach jest łatwiejszy niż po 30.

Sprawdź się — zadanie 1

Co sprawdzisz najpierw, gdy po kliknięciu przycisku nic się nie dzieje?

Pokaż przykładową odpowiedź

Konsolę (F12) pod kątem błędów, potem czy skrypt jest poprawnie wczytany (Network) oraz czy nazwa funkcji w onclick zgadza się z definicją.

Sprawdź się — zadanie 2

Skąd błąd Cannot read properties of null (reading 'style') po otwarciu strony?

Pokaż przykładową odpowiedź

Skrypt próbuje zmienić styl elementu, którego jeszcze nie ma (lub nie znaleziono go przez selektor); trzeba dodać defer, przenieść skrypt na koniec body lub poprawić selektor.

Ćwiczenia interaktywne: uzupełnij i popraw kod

Wpisz brakujące fragmenty w polach albo popraw kod w oknie i kliknij „Sprawdź”. Białe znaki i rodzaj cudzysłowu nie mają znaczenia. Rozwiązane ćwiczenia zapisują się na koncie i liczą się do odznak.

Ćwiczenie interaktywne — uzupełnij kod

Sprawdź wartość zmiennej i jej typ podczas debugowania.

console.(wartosc);
console.log( wartosc);
Ćwiczenie interaktywne — popraw kod

Skrypt zgłasza błąd, bo element nie został znaleziony: selektor klasy nie ma kropki. Popraw kod.

Ćwiczenie interaktywne — popraw kod

Skrypt zgłasza błąd „Unexpected token”: w kodzie brakuje nawiasu zamykającego. Popraw kod.

Ćwiczenie interaktywne — popraw kod

Wynik porównania liczb z pola jest błędny („10” jest uznane za mniejsze od „9”), bo porównywane są napisy. Zamień wartości na liczby.

Ćwiczenie interaktywne — uzupełnij kod

Uruchom kod dopiero po wczytaniu strony i obsłuż błąd w bloku try...catch.

document.addEventListener("DOMContentLoaded", () => {
     {
        start();
    }  (e) {
        console.error(e);
    }
});

Zadanie praktyczne

Zadanie próbne: karta produktu z wariantami

Szacowany czas: 60 minZakres: Lekcje 8–21Forma: pliki index.html, styl.css, main.js

Zadanie

Wykonaj kartę produktu dla sklepu z rowerami (własny projekt wizualny). Pliki obrazów: js-galeria.zip.

Założenia

  • Blok sekcji: obraz główny (klasa obraz) i trzy miniatury (klasa miniatury). Kliknięcie miniatury podmienia obraz główny na wybrany, kliknięcie obrazu głównego otwiera okno z jego powiększeniem (klasa okno, ukryte w CSS), kliknięcie znaku × zamyka okno.
  • Artykuł z listą rozwijaną „Wariant: czerwony / niebieski / czarny”. Po zmianie wartości listy skrypt zmienia kolor tła bloku nagłówkowego (style.backgroundColor) na odpowiedni.
  • Pole liczbowe „Liczba sztuk” (1–5) i przycisk „Dodaj do koszyka”. Skrypt wylicza cenę (np. 1499 zł × liczba) i wypisuje w akapicie „W koszyku: 2 szt., razem 2998.00 zł”; dla niepoprawnej liczby wypisuje „Podaj liczbę od 1 do 5”.
  • W stopce, po załadowaniu strony, wypisz dzisiejszą datę DD.MM.RRRR oraz licznik odwiedzin z localStorage.
  • Wszystkie funkcje o znaczących nazwach, obsługa zdarzeń przez atrybuty HTML i/lub addEventListener; brak błędów w konsoli.

Ocenie podlegać będzie

  • działanie galerii i okna,
  • poprawna obsługa listy i obliczeń,
  • walidacja liczby sztuk,
  • data i licznik,
  • czytelność i zgodność z wymaganiami.
Wskazówki
  • Wariant koloru: obiekt {czerwony: "#fecaca", ...} i odczyt przez kolory[lista.value].
  • Kontrola liczby: Number.isInteger(n) && n >= 1 && n <= 5.
  • Wzorce: lekcje 15, 19 i 14.

Zadanie praktyczne

Zadanie próbne: gra w zgadywanie liczby

Szacowany czas: 45 minZakres: Lekcje 8–21Forma: pliki gra.html, styl.css, main.js

Zadanie

Zaprojektuj prostą grę „Zgadnij liczbę”. Komputer losuje liczbę 1–50, a gracz ma 6 prób.

Założenia

  • Po załadowaniu strony skrypt losuje liczbę (Math.floor(Math.random() * 50) + 1) i zapisuje ją w zmiennej poza funkcją; ustawia licznik prób na 6.
  • Pole liczbowe i przycisk „Sprawdź”. Po kliknięciu skrypt porównuje liczbę z wylosowaną i w akapicie wypisuje: „za mało”, „za dużo” lub „Brawo! Zgadłeś w N próbie”; po wyczerpaniu prób wypisuje wylosowaną liczbę i blokuje pole (disabled).
  • Lista użytych prób (elementy li dodawane przez createElement) pokazuje każdy wpisany typ i wynik.
  • Przycisk „Nowa gra” zeruje stan, czyści listę, odblokowuje pole i losuje nową liczbę.
  • Najlepszy wynik (najmniej prób) zapisz w localStorage i wyświetlaj w stopce.

Ocenie podlegać będzie

  • poprawna logika gry i stan zmiennych,
  • tworzenie elementów DOM,
  • blokowanie i odblokowanie kontrolek,
  • zapis w localStorage,
  • czytelny kod.
Wskazówki
  • Stan gry: zmienne tajna i proby poza funkcjami.
  • Koniec gry: pole.disabled = true.
  • Lekcje 11, 14 i 20.