JavaScript od podstaw — w stronę INF.03
Każdy temat ma tę samą budowę: krótkie wyjaśnienie, potem przykład z gotowym rozwiązaniem (rozwiń, żeby zobaczyć kod), a obok analogiczne zadanie — bez rozwiązania, do zrobienia samodzielnie tą samą metodą.
Jak umieszczamy JavaScript?
JavaScript można umieścić na dwa sposoby: wewnątrz HTML (szybkie testy) i na zewnątrz w osobnym pliku .js (tak robimy na egzaminie INF.03 i w całym tym materiale).
Cały kod piszesz między tagami <script> i </script>. Najlepiej na samym końcu <body>, żeby HTML już istniał.
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<h1 id="tytul">Cześć!</h1>
<!-- JS wewnątrz -->
<script>
const el = document.getElementById("tytul");
el.textContent = "Działa JS wewnątrz!";
console.log("Wersja wewnętrzna");
</script>
</body>
</html>
To ten sposób używamy w kursie i na egzaminie. Plik HTML wygląda tak:
<!-- index.html -->
<h1 id="tytul">Cześć!</h1>
<!-- podłączamy plik JS -->
<script src="script.js"></script>
A plik JS wygląda tak (bez żadnych tagów HTML):
// script.js
const el = document.getElementById("tytul");
el.textContent = "Działa JS z zewnątrz!";
console.log("Wersja zewnętrzna");
Zasada: index.html + style.css + script.js w jednym folderze. Tagi <script> zawsze na końcu body.
Zmienne, stałe, wypisywanie danych
let deklaruje zmienną (wartość może się zmienić), const deklaruje stałą (wartość stała). Dane można wypisać w konsoli przeglądarki (console.log()), oknem alert(), albo pobrać od użytkownika oknem prompt().
Zdefiniuj zmienną liczba i przypisz jej wartość 42. Wyświetl ją w konsoli.
Rozwiązanie
let liczba = 42;
console.log(liczba);Zdefiniuj zmienną temperatura i przypisz jej dzisiejszą temperaturę powietrza (dowolna liczba). Wyświetl ją w konsoli.
// napisz kod samodzielnie, korzystając z przykładu obok
Stwórz stałą PI o wartości 3.14159 i wyświetl ją za pomocą alert().
Rozwiązanie
const PI = 3.14159;
alert(PI);Stwórz stałą LICZBA_UCZNIOW o wartości 28 i wyświetl ją za pomocą alert().
Zadeklaruj zmienne imie, nazwisko, wiek i wyświetl je jako zdanie w konsoli, łącząc tekst operatorem +.
Rozwiązanie
let imie = "Anna";
let nazwisko = "Kowalska";
let wiek = 19;
console.log(imie + " " + nazwisko + " ma " + wiek + " lat.");Zadeklaruj zmienne przedmiot, nauczyciel, ocena. Wyświetl w konsoli zdanie w stylu: „Z przedmiotu [przedmiot] u [nauczyciel] mam ocenę [ocena].”
Poproś użytkownika o ulubiony kolor za pomocą prompt(), a następnie wyświetl komunikat w konsoli.
Rozwiązanie
let kolor = prompt("Podaj swój ulubiony kolor:");
console.log("Twój ulubiony kolor to: " + kolor);Poproś użytkownika o ulubiony serial (prompt()) i wyświetl w konsoli: „Twój ulubiony serial to: [nazwa]”.
Wstrzykiwanie HTML do elementu
document.getElementById("id") znajduje element na stronie po jego identyfikatorze. Właściwość .innerHTML pozwala wstawić do niego dowolny tekst lub kod HTML. Template strings (odwrócone apostrofy `...` ze składnią ${zmienna}) pozwalają wygodnie wstawiać wartości do tekstu.
Stwórz <div id="wynik"></div>. Zdefiniuj a = 30 i b = 10, a wynik ich dodawania wstaw do diva.
Rozwiązanie
<div id="wynik"></div>
let a = 30;
let b = 10;
document.getElementById("wynik").innerHTML = a + b;Stwórz <div id="suma"></div>. Zdefiniuj a = 15 i b = 7, wynik dodawania wstaw do tego diva.
To samo co wyżej, ale wynik ma się pojawić jako nagłówek <h1>, dla a = 50, b = 20.
Rozwiązanie
let a = 50;
let b = 20;
document.getElementById("wynik").innerHTML = "<h1>" + (a + b) + "</h1>";Stwórz <div id="roznica"></div>, dla a = 90, b = 35 wstaw wynik odejmowania jako nagłówek <h2>.
Ten sam efekt co wyżej, ale zapisany za pomocą template strings, dla a = 100, b = 200.
Rozwiązanie
let a = 100;
let b = 200;
document.getElementById("wynik").innerHTML = `<h1>${a + b}</h1>`;Za pomocą template strings, dla <div id="iloczyn"></div>, a = 6, b = 9, wstaw jako <h1> tekst: „Iloczyn to: [wynik]”.
Pętle
Pętla for jest wygodna, gdy z góry wiadomo ile razy coś się powtórzy. while sprawdza warunek przed każdym wykonaniem — jeśli warunek jest fałszywy od razu, ciało pętli nie wykona się ani razu. do...while sprawdza warunek po wykonaniu — ciało zawsze wykona się co najmniej raz.
W <div id="wynik"></div> wyświetl liczby od 1 do 100, rozdzielone przecinkami.
Rozwiązanie
let tekst = "";
for (let i = 1; i <= 100; i++) {
tekst += i;
if (i < 100) tekst += ", ";
}
document.getElementById("wynik").innerHTML = tekst;W <div id="parzyste"></div> wyświetl liczby parzyste od 2 do 50, rozdzielone przecinkami (podpowiedź: krok pętli i += 2).
Wyświetl tabelę HTML z dwiema kolumnami: liczby 0–9 i ich kwadraty. Dodaj obramowanie w CSS.
Rozwiązanie
let tabela = "<table id='kwadraty'>";
for (let i = 0; i <= 9; i++) {
tabela += `<tr><td>${i}</td><td>${i * i}</td></tr>`;
}
tabela += "</table>";
document.getElementById("wynik").innerHTML = tabela;CSS do obramowania
#kwadraty, #kwadraty td {
border: 1px solid #333;
border-collapse: collapse;
padding: 4px 10px;
}Zbuduj tabelę z dwiema kolumnami: liczby 1–5 i ich sześciany (i ** 3). Dodaj CSS z obramowaniem komórek.
Porównaj while i do...while, gdy warunek jest fałszywy od samego początku.
Rozwiązanie
let licznik = 10;
while (licznik < 5) {
console.log("To nie wykona się ani razu");
licznik++;
}
let licznik2 = 10;
do {
console.log("To wykona się raz, mimo że warunek jest fałszywy");
licznik2++;
} while (licznik2 < 5);Napisz własny przykład z while i do...while, gdzie warunek startowy jest od razu fałszywy (np. x = 100, warunek x < 10). W konsoli skomentuj, ile razy wykonało się ciało każdej z pętli.
Instrukcje warunkowe
if / else, operator trójargumentowy ? :, łańcuch if / else if / else oraz switch — cztery sposoby na to samo pytanie: „co zrobić w zależności od wartości?”.
Jeśli liczba jest dodatnia, w <div id="opis"></div> wyświetl jako <h1> tekst „Liczba większa od zera.”, w przeciwnym razie „Zero lub liczba ujemna.”.
Rozwiązanie
let liczba = 7;
let opis = document.getElementById("opis");
if (liczba > 0) {
opis.innerHTML = "<h1>Liczba większa od zera.</h1>";
} else {
opis.innerHTML = "Zero lub liczba ujemna.";
}Zdefiniuj zmienną wiek. Jeśli wiek >= 18, w <div id="opis"></div> wyświetl jako <h1> „Pełnoletni”, w przeciwnym razie „Niepełnoletni”.
To samo pytanie o znak liczby, ale zapisane operatorem ? :.
Rozwiązanie
let liczba = -4;
document.getElementById("opis").innerHTML =
liczba > 0 ? "dodatnia" : "0/ujemna";Zdefiniuj zmienną temperatura. Operatorem ? : wyświetl w <div id="opis"></div> „ciepło” gdy jest większa lub równa 15, w przeciwnym razie „zimno”.
Rozróżnij trzy przypadki liczby: dodatnia / ujemna / zero, za pomocą if / else if / else.
Rozwiązanie
let liczba = 0;
let opis = document.getElementById("opis");
if (liczba > 0) {
opis.innerHTML = "<h1>Liczba większa od zera.</h1>";
} else if (liczba < 0) {
opis.innerHTML = "Liczba ujemna.";
} else {
opis.innerHTML = "Zero";
}Zdefiniuj wynik punktowy egzaminu (0–100). Za pomocą if / else if / else w <div id="opis"></div> wyświetl: „celujący” (≥90), „dobry” (≥75), „dostateczny” (≥50), w przeciwnym razie „niedostateczny”.
Dla oceny szkolnej (1–6) wypisz jej opis słowny za pomocą switch, w <div id="opisoceny"></div>.
Rozwiązanie
let ocena = 4;
let opisOceny = "";
switch (ocena) {
case 1: opisOceny = "niedostateczny"; break;
case 2: opisOceny = "dopuszczający"; break;
case 3: opisOceny = "dostateczny"; break;
case 4: opisOceny = "dobry"; break;
case 5: opisOceny = "bardzo dobry"; break;
case 6: opisOceny = "celujący"; break;
default: opisOceny = "nieprawidłowa ocena";
}
document.getElementById("opisoceny").innerHTML = opisOceny;Za pomocą switch, dla numeru dnia tygodnia (1–7), wypisz jego nazwę w <div id="dzien"></div>.
Funkcje
Funkcja to nazwany fragment kodu, który przyjmuje argumenty i (opcjonalnie) coś zwraca poleceniem return. Dzięki temu ten sam kod można wywołać wielokrotnie, z różnymi danymi.
Napisz funkcję policzSume(a, b), która zwraca sumę dwóch liczb. Wywołaj ją i wypisz wynik w konsoli.
Rozwiązanie
function policzSume(a, b) {
return a + b;
}
console.log(policzSume(12, 8));Napisz funkcję policzRoznice(a, b), która zwraca różnicę dwóch liczb. Wywołaj ją i wypisz wynik w konsoli.
Napisz funkcję sprawdzParzystosc(liczba), która zwraca true, jeśli liczba jest parzysta.
Rozwiązanie
function sprawdzParzystosc(liczba) {
return liczba % 2 === 0;
}
console.log(sprawdzParzystosc(17));
console.log(sprawdzParzystosc(20));Napisz funkcję czyPelnoletni(wiek), która zwraca true lub false. Wywołaj ją z kilkoma przykładowymi wartościami.
Tablice — podstawy
Tablica przechowuje wiele wartości pod jedną nazwą. Przydatne właściwości i metody: .length, .push() / .pop() (koniec tablicy), .unshift() / .shift() (początek tablicy), .sort(), .reverse(), oraz pętla for...of do przechodzenia po elementach.
Zdefiniuj tablicę liczb, wypisz ją w konsoli jako całość oraz wyświetl jej długość.
Rozwiązanie
let liczby = [5, 12, 17, 23, 123, 45, 54];
console.log(liczby);
console.log(liczby.length);Zdefiniuj tablicę ["Fiat","Skoda","Volvo","Mercedes"]. Wypisz ją w konsoli w całości oraz wyświetl jej długość.
Wypisz zawartość tablicy do <div id="tablica"></div> za pomocą pętli for...of, rozdzieloną przecinkami.
Rozwiązanie
let liczby = [5, 12, 17, 23, 123, 45, 54];
let tekst = "";
for (const l of liczby) {
tekst += l + ", ";
}
document.getElementById("tablica").innerHTML = tekst;Wypisz tablicę marek samochodów z poprzedniego zadania do <div id="marki"></div> za pomocą pętli for...of, rozdzieloną przecinkami.
Dodaj do tablicy dwie liczby na końcu (push), a potem usuń ostatni element (pop). Wypisuj tablicę w konsoli po każdej zmianie.
Rozwiązanie
let liczby = [5, 12, 17, 23, 123, 45, 54];
liczby.push(201, 1);
console.log(liczby);
liczby.pop();
console.log(liczby.length, liczby);Do tablicy marek samochodów dodaj na początku dwie nowe marki (unshift): „Kia” i „Opel”. Następnie usuń pierwszy element (shift). Wypisz długość i zawartość tablicy w konsoli po każdej zmianie.
Posortuj alfabetycznie tablicę imion i wyświetl wynik w konsoli.
Rozwiązanie
let osoby = ["Zenek", "Tomasz", "Adam", "Ewa", "Krzysztof"];
osoby.sort();
console.log(osoby);Zdefiniuj tablicę kilku liczb w losowej kolejności i posortuj ją malejąco. Podpowiedź: .sort() domyślnie sortuje jako tekst, dla liczb malejąco potrzebna jest funkcja porównująca: .sort((a, b) => b - a).
Obsługa zdarzeń
Metoda .addEventListener("zdarzenie", funkcja) "podpina" reakcję pod element — najczęściej na kliknięcie ("click") lub zmianę wartości ("input"). Wewnątrz funkcji obsługującej zdarzenie słowo this wskazuje na element, który wywołał zdarzenie. document.querySelectorAll() zwraca listę wielu elementów naraz, po której można przejść pętlą for...of.
Po kliknięciu przycisku „Powitaj!” wyświetl tekst „Witaj świecie!” jako <h1>, a sam przycisk ma zniknąć.
Rozwiązanie
<button id="btnPowitaj">Powitaj!</button>
<div id="wynik"></div>
document.getElementById("btnPowitaj").addEventListener("click", function () {
document.getElementById("wynik").innerHTML = "<h1>Witaj świecie!</h1>";
document.getElementById("btnPowitaj").style.display = "none";
});Stwórz przycisk „Pożegnaj!”, który po kliknięciu wyświetli jako <h2> tekst „Do zobaczenia!” i sam zniknie.
Stwórz suwak (<input type="range">) o zakresie 0–100. Poniżej wyświetlaj aktualnie ustawioną wartość w <div id="liczba"></div>.
Rozwiązanie
<input type="range" id="suwak" min="0" max="100" value="0">
<div id="liczba">0</div>
document.getElementById("suwak").addEventListener("input", function () {
document.getElementById("liczba").innerHTML = this.value;
});Stwórz suwak głośności o zakresie 0–10, wartość początkowa 5. Poniżej wyświetlaj aktualną wartość jako tekst „Głośność: [wartość]”.
Stwórz trzy przyciski: „jeden”, „dwa”, „trzy”. Po kliknięciu na dowolny z nich pokaż komunikat „Kliknąłeś na przycisk [nazwa]”, wykorzystując this.
Rozwiązanie
<button>jeden</button>
<button>dwa</button>
<button>trzy</button>
<div id="opis"></div>
const przyciski = document.querySelectorAll("button");
for (const przycisk of przyciski) {
przycisk.addEventListener("click", function () {
document.getElementById("opis").innerHTML = "Kliknąłeś na przycisk " + this.innerHTML;
});
}Stwórz przycisk, <div> i <span>, każdy z własnym id. Za pomocą querySelectorAll, pętli for...of i this wyświetl w <div id="opis"></div> identyfikator klikniętego elementu.
Formularze
Wartość pola formularza odczytuje się przez .value — dla pól tekstowych i liczbowych jest to zawsze tekst, dlatego liczby trzeba jawnie skonwertować (Number()). <select>, radio i checkbox reagują na zdarzenie "change".
Po kliknięciu przycisku „Pokaż” przepisz wartość z pola number do <div id="wynik"></div> jako <h1>. Sprawdź w konsoli typ odczytanej wartości.
Rozwiązanie
<input type="number" id="pole">
<button id="btnPokaz">Pokaż</button>
<div id="wynik"></div>
document.getElementById("btnPokaz").addEventListener("click", function () {
let liczba = document.getElementById("pole").value;
console.log(typeof liczba);
liczba = Number(liczba);
console.log(typeof liczba);
document.getElementById("wynik").innerHTML = `<h1>${liczba}</h1>`;
});Zmodyfikuj zadanie tak, aby po kliknięciu przycisku wypisywała się druga potęga wpisanej liczby (liczba ** 2).
Zbuduj „dodawacz”: po kliknięciu przycisku „=” dodaj dwie liczby wpisane w pola tekstowe i wyświetl wynik.
Rozwiązanie
<input type="number" id="pole1">
+
<input type="number" id="pole2">
<button id="btnRowna">=</button>
<div id="wynik"></div>
document.getElementById("btnRowna").addEventListener("click", function () {
let a = Number(document.getElementById("pole1").value);
let b = Number(document.getElementById("pole2").value);
document.getElementById("wynik").innerHTML = a + b;
});Zbuduj podobny kalkulator, ale mnożący dwie wpisane liczby po kliknięciu przycisku „×”.
Utwórz listę rozwijaną z nazwami pasm górskich. Wybranie pasma ma wyświetlić nazwę i wysokość jego najwyższego szczytu.
Rozwiązanie
<select id="pasmo">
<option value="">Wybierz pasmo</option>
<option value="Tatry">Tatry</option>
<option value="Karkonosze">Karkonosze</option>
<option value="Bieszczady">Bieszczady</option>
</select>
<div id="opis"></div>
const szczyty = {
Tatry: "Rysy, 2499 m",
Karkonosze: "Śnieżka, 1603 m",
Bieszczady: "Tarnica, 1346 m"
};
document.getElementById("pasmo").addEventListener("change", function () {
document.getElementById("opis").innerHTML = `${this.value}: ${szczyty[this.value]}`;
});Zbuduj listę rozwijaną z nazwami trzech polskich miast. Wybranie miasta ma wyświetlić w div-ie liczbę jego mieszkańców (wymyśl przykładowe dane).
Wstaw trzy pola typu radio z wartościami 200, 300, 500. Wybór opcji ma wyświetlić jej wartość w div-ie poniżej.
Rozwiązanie
<input type="radio" name="cena" value="200"> 200 zł
<input type="radio" name="cena" value="300"> 300 zł
<input type="radio" name="cena" value="500"> 500 zł
<div id="wynik"></div>
const opcje = document.querySelectorAll('input[name="cena"]');
for (const opcja of opcje) {
opcja.addEventListener("change", function () {
document.getElementById("wynik").innerHTML = this.value;
});
}Dodaj pole typu checkbox z podpisem „Zapoznałem się z regulaminem”. Jego zaznaczenie ma wyświetlić jako <h2> tekst „Pamiętaj! Koniecznie przeczytaj nasz regulamin”.
Zmiana i odczyt CSS przez JS
Właściwość element.style.nazwaWlasciwosci pozwala odczytać lub ustawić styl elementu bezpośrednio z JavaScriptu (np. .style.backgroundColor). Do odczytu stylu nadanego przez arkusz CSS (a nie ustawionego inline) służy getComputedStyle(element).
Po kliknięciu przycisku „Zmień tło” zmień kolor tła strony na żółty.
Rozwiązanie
<button id="btnTlo">Zmień tło</button>
document.getElementById("btnTlo").addEventListener("click", function () {
document.body.style.backgroundColor = "yellow";
});Utwórz div 300×300 pikseli z czarnym obramowaniem oraz dwa przyciski: „Czerwone tło” i „Zielone tło”. Kliknięcie ma zmieniać kolor tła diva na odpowiedni.
Stwórz suwak zmieniający rozmiar diva w zakresie 0–500 pikseli, wartość początkowa 300. Obok wyświetlaj aktualny rozmiar.
Rozwiązanie
<input type="range" id="suwak" min="0" max="500" value="300">
<span id="opis">300px</span>
<div id="kwadrat" style="width:300px; height:300px; background:#4FD1C5;"></div>
document.getElementById("suwak").addEventListener("input", function () {
document.getElementById("kwadrat").style.width = this.value + "px";
document.getElementById("kwadrat").style.height = this.value + "px";
document.getElementById("opis").innerHTML = this.value + "px";
});Stwórz suwak zmieniający rozmiar czcionki akapitu w zakresie 0–250 pikseli, wartość początkowa 14.
Stwórz stronę z czarnym tłem i suwakiem zmieniającym składową R (czerwoną) koloru tła w zakresie 0–255, domyślnie 0.
Rozwiązanie
<input type="range" id="r" min="0" max="255" value="0">
let r = 0, g = 0, b = 0;
document.getElementById("r").addEventListener("input", function () {
r = this.value;
document.body.style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
});Rozbuduj przykład o dwa kolejne suwaki (G i B), każdy w zakresie 0–255, wartość początkowa 255 (biel). Zmiana dowolnego suwaka ma aktualizować kolor tła i wyświetlać aktualną wartość tej składowej.
Umieść na stronie słowo napisane na czerwono. Po kliknięciu na nie wyświetl w konsoli jego kolor, odczytany z CSS za pomocą getComputedStyle.
Rozwiązanie
<span id="slowo" style="color:red;">czerwony</span>
document.getElementById("slowo").addEventListener("click", function () {
const styl = getComputedStyle(this);
console.log(styl.color);
});Umieść na stronie trzy słowa: napisane na czerwono, zielono i niebiesko. Kliknięcie na dowolne z nich ma wyświetlić jego kolor w <div id="opis"></div> (podpowiedź: querySelectorAll + this).
Tablice cz. 2
Poza podstawowymi metodami tablic warto znać: Array.isArray() (czy coś jest tablicą), .join() (łączy elementy w tekst), .slice() (wycina fragment, nie zmieniając oryginału), .splice() (usuwa i/lub dodaje elementy, zmieniając oryginał) oraz .split() na tekście (dzieli tekst na tablicę słów). Tekst można też odczytywać znak po znaku jak tablicę, np. tekst[0].
Sprawdź, czy tablica osoby rzeczywiście jest tablicą, i wypisz odpowiedni komunikat na stronie.
Rozwiązanie
let osoby = ["Jan Nowak", "Kazimierz Zyga", "Stefan Koc", "Ewa Mocek", "Mariusz Abramski"];
if (Array.isArray(osoby)) {
document.getElementById("opis").innerHTML = "osoby to tablica";
} else {
document.getElementById("opis").innerHTML = "osoby to nie tablica";
}Zdefiniuj zmienną miasto = "Wrocław". Sprawdź, czy jest tablicą, i wyświetl odpowiedni komunikat.
Mając tablicę osoby, wyświetl jej elementy w jednej linii rozdzielone przecinkami (.join()), a następnie każdy w osobnym akapicie.
Rozwiązanie
<div id="wynik1"></div>
<div id="wynik2"></div>
let osoby = ["Jan Nowak", "Kazimierz Zyga", "Stefan Koc", "Ewa Mocek", "Mariusz Abramski"];
document.getElementById("wynik1").innerHTML = osoby.join(", ");
let akapity = "";
for (const osoba of osoby) {
akapity += `<p>${osoba}</p>`;
}
document.getElementById("wynik2").innerHTML = akapity;Mając tablicę samochody = ["Fiat","Skoda","Volvo","Mercedes","Kia"], stwórz nową tablicę nazwyKrotkie zawierającą tylko modele o nazwie krótszej niż 5 znaków, a następnie wypisz ją za pomocą .join().
Ze względu na RODO nie chcesz wyświetlać imion i nazwisk — zamiast dwóch pierwszych elementów tablicy wypisz w konsoli słowo „tajne”, korzystając z .slice() i tworząc nową tablicę do wyświetlenia.
Rozwiązanie
let samochody = ["Fiat", "Skoda", "Volvo", "Mercedes", "Kia", "Opel", "Citroen"];
let doWyswietlenia = ["tajne", "tajne", ...samochody.slice(2)];
console.log(doWyswietlenia);Mając tablicę osoby, wytnij (.slice()) dwa pierwsze elementy do osobnej tablicy i wyświetl w konsoli zarówno wycięty fragment, jak i oryginalną tablicę (niezmienioną).
Z tablicy osoby usuń „Ewa Mocek” i w to samo miejsce dodaj dwie nowe osoby, korzystając z .splice().
Rozwiązanie
let osoby = ["Jan Nowak", "Kazimierz Zyga", "Stefan Koc", "Ewa Mocek", "Mariusz Abramski"];
let indeks = osoby.indexOf("Ewa Mocek");
let usuniete = osoby.splice(indeks, 1, "Maria Kapik", "Elżbieta Konf");
console.log(usuniete);
console.log(osoby);Z tablicy samochody usuń element „Volvo” za pomocą .splice() (bez dodawania niczego w zamian). Wypisz w konsoli usunięty element oraz tablicę po zmianie.
Podany tekst podziel na wyrazy (.split(" ")) i każdy wyraz wyświetl jako osobny element z żółtym tłem.
Rozwiązanie
let zdanie = "JavaScript jest językiem programowania webowego.";
let wyrazy = zdanie.split(" ");
let html = "";
for (const wyraz of wyrazy) {
html += `<span style="background:yellow; margin-right:4px;">${wyraz}</span>`;
}
document.getElementById("wynik").innerHTML = html;Weź dowolne zdanie o sobie (np. „Uczę się JavaScript do egzaminu INF.03.”), podziel je na wyrazy i wyświetl każdy z nich jako osobny element z jasnoniebieskim tłem. Dodatkowo wyświetl w konsoli pierwszą literę zdania, odczytaną jak z tablicy (zdanie[0]).
Mini-projekt: lista zadań (to-do list)
To zadanie łączy wszystko z poprzednich sekcji: zdarzenia, formularz, tablicę jako magazyn danych i zmianę stylu elementów. Brak tu gotowego rozwiązania — to samodzielny projekt, rozpisany na kroki.
Cel: strona z polem tekstowym, przyciskiem „Dodaj” i listą zadań poniżej. Każde zadanie da się oznaczyć jako zrobione i usunąć.
Krok 1 — HTML. Dodaj <input type="text" id="nowe">, <button id="btnDodaj">Dodaj</button> oraz pusty <div id="lista"></div>, w którym pojawi się lista zadań.
Krok 2 — magazyn danych. Zdefiniuj pustą tablicę let zadania = [];. To w niej, a nie tylko na ekranie, ma żyć aktualny stan listy.
Krok 3 — funkcja renderująca. Napisz funkcję rysujListe(), która czyści <div id="lista"> i za pomocą pętli for...of (lub forEach) buduje od nowa listę na podstawie tablicy zadania — każde zadanie w osobnym <div>, z przyciskiem „✓” (oznacz) i „✕” (usuń) obok tekstu.
Krok 4 — dodawanie. Pod przyciskiem „Dodaj” podepnij addEventListener("click", ...): pobierz wartość z pola tekstowego, dodaj ją do tablicy zadania (.push()), wywołaj ponownie rysujListe() i wyczyść pole tekstowe.
Krok 5 — oznaczanie jako zrobione. Zamiast zwykłego tekstu, przechowuj w tablicy obiekty { tekst: "...", zrobione: false }. Kliknięcie „✓” ma przełączać zrobione na przeciwną wartość i wywoływać rysujListe(). W funkcji renderującej dodaj zadaniom oznaczonym jako zrobione styl text-decoration: line-through.
Krok 6 — usuwanie. Kliknięcie „✕” ma usuwać dany element z tablicy (.splice(), po znalezionym indeksie) i ponownie wywoływać rysujListe().
Krok 7 (dodatkowo). Dodaj licznik pod listą pokazujący, ile zadań zostało do zrobienia (.filter() po tablicy zadania).
Typowe zadania egzaminacyjne
Od tego miejsca sekcje odpowiadają zadaniom, jakie realnie pojawiają się na egzaminie praktycznym INF.03: walidacja danych z formularza, obliczenia „biznesowe” (ceny, rabaty, VAT), operacje na tablicach obiektów oraz budowanie tabel wynikowych. Ten sam układ co wcześniej — przykład z rozwiązaniem obok zadania do samodzielnego wykonania.
Walidacja formularza (wyrażenia regularne)
Egzamin bardzo często wymaga sprawdzenia poprawności danych z formularza, zanim zostaną „wysłane” lub przetworzone. Wyrażenie regularne (RegExp) zapisuje się między ukośnikami, np. /^[0-9]{9}$/, a metoda .test(tekst) zwraca true lub false. Typowo: pokazujemy komunikat błędu i/lub czerwoną ramkę, gdy dane są niepoprawne.
Pole <input id="email"> i przycisk „Sprawdź”. Po kliknięciu sprawdź, czy wpisany tekst jest poprawnym adresem e-mail (uproszczony wzorzec), i wyświetl komunikat w <div id="blad"></div>.
Rozwiązanie
<input type="text" id="email" placeholder="adres e-mail">
<button id="btnSprawdz">Sprawdź</button>
<div id="blad"></div>
const wzorzec = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
document.getElementById("btnSprawdz").addEventListener("click", function () {
const wartosc = document.getElementById("email").value;
const blad = document.getElementById("blad");
if (wzorzec.test(wartosc)) {
blad.innerHTML = "Adres e-mail wygląda poprawnie.";
blad.style.color = "green";
} else {
blad.innerHTML = "Niepoprawny adres e-mail.";
blad.style.color = "red";
}
});Pole <input id="telefon"> i przycisk „Sprawdź”. Sprawdź, czy wpisany numer telefonu składa się dokładnie z 9 cyfr (bez spacji i myślników). Wyświetl odpowiedni komunikat w <div id="blad2"></div> (podpowiedź: wzorzec /^[0-9]{9}$/).
Formularz z polami imie i wiek. Po kliknięciu „Wyślij” zablokuj domyślną akcję formularza (event.preventDefault()), sprawdź czy imie nie jest puste i czy wiek jest liczbą z zakresu 1–120. Zbierz błędy w tablicy i wyświetl je jako listę.
Rozwiązanie
<form id="formularz">
<input type="text" id="imie" placeholder="imię">
<input type="text" id="wiek" placeholder="wiek">
<button type="submit">Wyślij</button>
</form>
<div id="bledy"></div>
document.getElementById("formularz").addEventListener("submit", function (event) {
event.preventDefault();
const imie = document.getElementById("imie").value;
const wiek = Number(document.getElementById("wiek").value);
let bledy = [];
if (imie.trim() === "") bledy.push("Imię nie może być puste.");
if (isNaN(wiek) || wiek < 1 || wiek > 120) bledy.push("Wiek musi być liczbą od 1 do 120.");
const box = document.getElementById("bledy");
if (bledy.length === 0) {
box.innerHTML = "Formularz poprawny, dane wysłane.";
box.style.color = "green";
} else {
box.innerHTML = "<ul>" + bledy.map(b => `<li>${b}</li>`).join("") + "</ul>";
box.style.color = "red";
}
});Formularz rejestracyjny z polami login i haslo. Po kliknięciu „Zarejestruj” (bez przeładowania strony) sprawdź: czy login ma co najmniej 3 znaki oraz czy haslo ma co najmniej 8 znaków. Zbierz błędy w tablicy i wyświetl je jako listę, tak jak w przykładzie.
Podczas pisania w polu <input id="kod"> (zdarzenie "input", na bieżąco) sprawdzaj, czy tekst pasuje do formatu kodu pocztowego NN-NNN, i koloruj ramkę pola na zielono lub czerwono.
Rozwiązanie
const wzorzec = /^[0-9]{2}-[0-9]{3}$/;
const pole = document.getElementById("kod");
pole.addEventListener("input", function () {
if (wzorzec.test(pole.value)) {
pole.style.borderColor = "green";
} else {
pole.style.borderColor = "red";
}
});Zrób analogiczną walidację „na bieżąco” dla pola <input id="tablicaRej">, sprawdzając format polskiej tablicy rejestracyjnej: 2–3 litery, myślnik, 4–5 znaków alfanumerycznych (np. DW-12345). Podpowiedź: wzorzec /^[A-Z]{2,3}-[A-Z0-9]{4,5}$/.
Obliczenia biznesowe (cena, rabat, VAT)
Klasyczny egzaminacyjny scenariusz: użytkownik podaje ilość i cenę, program liczy sumę, ewentualny rabat i/lub podatek. Warto pamiętać o Number() przy odczycie z pola tekstowego oraz o .toFixed(2), żeby wynik pieniężny miał dwa miejsca po przecinku.
Pola ilosc i cena. Po kliknięciu „Oblicz” pokaż sumę; jeśli ilosc > 10, zastosuj 10% rabatu od sumy.
Rozwiązanie
<input type="text" id="ilosc" placeholder="ilość">
<input type="text" id="cena" placeholder="cena za sztukę">
<button id="btnOblicz">Oblicz</button>
<div id="wynik"></div>
document.getElementById("btnOblicz").addEventListener("click", function () {
const ilosc = Number(document.getElementById("ilosc").value);
const cena = Number(document.getElementById("cena").value);
let suma = ilosc * cena;
if (ilosc > 10) {
suma = suma * 0.9;
}
document.getElementById("wynik").innerHTML = `Do zapłaty: ${suma.toFixed(2)} zł`;
});Pola ilosc i cena. Oblicz sumę; jeśli suma przekracza 500 zł, zastosuj rabat 15%. Wyświetl wynik zaokrąglony do dwóch miejsc po przecinku wraz z informacją, czy rabat został zastosowany.
Mając kwotę netto z pola netto, po kliknięciu „Przelicz” wyświetl kwotę brutto przy stawce VAT 23%.
Rozwiązanie
document.getElementById("btnPrzelicz").addEventListener("click", function () {
const netto = Number(document.getElementById("netto").value);
const brutto = netto * 1.23;
document.getElementById("wynikVat").innerHTML = `Kwota brutto: ${brutto.toFixed(2)} zł`;
});Zrób odwrotne przeliczenie: mając kwotę brutto z pola brutto, oblicz i wyświetl kwotę netto oraz osobno kwotę samego podatku VAT (przy stawce 23%).
Formularz zamówienia: produkt (tekst), ilosc, cena. Po kliknięciu „Generuj podsumowanie” wyświetl czytelne podsumowanie zamówienia jako kilka linii tekstu (nazwa, ilość, cena jednostkowa, suma).
Rozwiązanie
document.getElementById("btnPodsumuj").addEventListener("click", function () {
const produkt = document.getElementById("produkt").value;
const ilosc = Number(document.getElementById("ilosc").value);
const cena = Number(document.getElementById("cena").value);
const suma = ilosc * cena;
document.getElementById("podsumowanie").innerHTML = `
<p>Produkt: ${produkt}</p>
<p>Ilość: ${ilosc}</p>
<p>Cena jednostkowa: ${cena.toFixed(2)} zł</p>
<p><strong>Suma: ${suma.toFixed(2)} zł</strong></p>
`;
});Formularz wynajmu sprzętu: pola dni, stawkaDzienna oraz <input type="checkbox" id="kaucja">. Oblicz koszt jako dni * stawkaDzienna, a jeśli checkbox jest zaznaczony, doliczy do sumy stałą kaucję 200 zł. Wyświetl czytelne podsumowanie jak w przykładzie.
Tablice obiektów — sortowanie i filtrowanie
Zadania egzaminacyjne często podają gotową tablicę obiektów (produkty, uczniowie, pracownicy) i każą ją posortować lub przefiltrować. .sort((a, b) => a.pole - b.pole) sortuje rosnąco po polu liczbowym (zamień kolejność a/b dla malejąco). .filter() zwraca nową tablicę spełniającą warunek, nie zmieniając oryginału.
Mając tablicę produktów z ceną, posortuj ją rosnąco po cenie i wyświetl listę w <div id="lista"></div>.
Rozwiązanie
let produkty = [
{ nazwa: "Klawiatura", cena: 120 },
{ nazwa: "Monitor", cena: 890 },
{ nazwa: "Myszka", cena: 60 },
{ nazwa: "Słuchawki", cena: 250 }
];
let posortowane = [...produkty].sort((a, b) => a.cena - b.cena);
let html = "";
for (const p of posortowane) {
html += `<p>${p.nazwa} — ${p.cena} zł</p>`;
}
document.getElementById("lista").innerHTML = html;Mając tablicę uczniowie = [{imie:"Ala", ocena:4}, {imie:"Bartek", ocena:6}, {imie:"Celina", ocena:3}, {imie:"Damian", ocena:5}], posortuj ją malejąco po ocenie i wyświetl listę „imię — ocena”.
Z tablicy produkty odfiltruj te tańsze niż 200 zł, wyświetl ich listę oraz ich liczbę.
Rozwiązanie
let tansze = produkty.filter(p => p.cena < 200);
let html = "";
for (const p of tansze) {
html += `<p>${p.nazwa} — ${p.cena} zł</p>`;
}
html += `<p><strong>Liczba produktów: ${tansze.length}</strong></p>`;
document.getElementById("wynikFiltr").innerHTML = html;Z tablicy uczniowie odfiltruj tych z oceną co najmniej 4 (>= 4), wyświetl ich listę oraz informację, ilu uczniów zdało.
Połącz filtrowanie i sortowanie: z tablicy produkty wybierz tylko te droższe niż 100 zł, posortuj je rosnąco po cenie, a wynik zbuduj jako tabelę HTML.
Rozwiązanie
let wynik = produkty
.filter(p => p.cena > 100)
.sort((a, b) => a.cena - b.cena);
let tabela = "<table><tr><th>Nazwa</th><th>Cena</th></tr>";
for (const p of wynik) {
tabela += `<tr><td>${p.nazwa}</td><td>${p.cena} zł</td></tr>`;
}
tabela += "</table>";
document.getElementById("tabelaProduktow").innerHTML = tabela;Z tablicy uczniowie wybierz tylko tych, którzy zdali (ocena >= 3), posortuj rosnąco po imieniu (a.imie.localeCompare(b.imie)) i zbuduj z nich tabelę HTML z kolumnami „Imię” i „Ocena”.
Dynamiczne tabele z danych i statystyki
Bardzo częsty schemat na egzaminie: mając gotową tablicę danych, wygenerować z niej tabelę HTML, a pod nią policzyć podsumowanie — sumę, średnią, wartość minimalną i maksymalną. Do sumy dobrze nadaje się .reduce(), do min/max Math.min(...tablica) / Math.max(...tablica).
Zbuduj tabelę z tablicy produkty (nazwa, cena, ilość), a pod nią wyświetl łączną wartość magazynu (suma cena * ilość dla wszystkich produktów).
Rozwiązanie
let produkty = [
{ nazwa: "Klawiatura", cena: 120, ilosc: 5 },
{ nazwa: "Monitor", cena: 890, ilosc: 2 },
{ nazwa: "Myszka", cena: 60, ilosc: 10 }
];
let tabela = "<table><tr><th>Nazwa</th><th>Cena</th><th>Ilość</th></tr>";
for (const p of produkty) {
tabela += `<tr><td>${p.nazwa}</td><td>${p.cena} zł</td><td>${p.ilosc}</td></tr>`;
}
tabela += "</table>";
document.getElementById("tabelaMagazyn").innerHTML = tabela;
let wartoscMagazynu = produkty.reduce((suma, p) => suma + p.cena * p.ilosc, 0);
document.getElementById("statystyki").innerHTML = `Łączna wartość magazynu: ${wartoscMagazynu.toFixed(2)} zł`;Mając tablicę uczniowie = [{imie:"Ala", ocena:4}, {imie:"Bartek", ocena:6}, {imie:"Celina", ocena:3}, {imie:"Damian", ocena:5}], zbuduj z niej tabelę (imię, ocena), a pod nią wyświetl średnią ocen w klasie (zaokrągloną do dwóch miejsc po przecinku).
W tabeli produktów podświetl na żółto wiersz z najdroższym produktem (dodaj mu klasę CSS podczas budowania tabeli).
Rozwiązanie
<style>
.najdrozszy { background: yellow; }
</style>
let ceny = produkty.map(p => p.cena);
let maksCena = Math.max(...ceny);
let tabela = "<table>";
for (const p of produkty) {
let klasa = p.cena === maksCena ? "najdrozszy" : "";
tabela += `<tr class="${klasa}"><td>${p.nazwa}</td><td>${p.cena} zł</td></tr>`;
}
tabela += "</table>";
document.getElementById("tabelaZKolorem").innerHTML = tabela;W tabeli uczniów podświetl na zielono wiersz ucznia z najwyższą oceną oraz na czerwono wiersz ucznia z najniższą oceną (podpowiedź: Math.min(...oceny), Math.max(...oceny), dwie klasy CSS).
Projekt egzaminacyjny: formularz zamówienia
Zadanie łączy wszystko z bloku egzaminacyjnego: walidację formularza, obliczenia i tablicę obiektów jako „koszyk” zamówień. Jak w mini-projekcie z sekcji 11 — brak gotowego rozwiązania, tylko kroki do samodzielnej realizacji.
Cel: formularz zamawiania produktów z walidacją danych, dodawaniem pozycji do koszyka i podsumowaniem z rabatem.
Krok 1 — HTML. Dodaj pola <input id="produkt">, <input id="ilosc">, <input id="cena">, przycisk <button id="btnDodaj">Dodaj do koszyka</button>, pusty <div id="koszyk"></div> na tabelę oraz <div id="podsumowanie"></div> na łączną kwotę.
Krok 2 — magazyn danych. Zdefiniuj pustą tablicę let koszyk = [];, w której każda pozycja to obiekt { produkt, ilosc, cena }.
Krok 3 — walidacja. Pod przyciskiem „Dodaj do koszyka” sprawdź: czy pole produkt nie jest puste, czy ilosc jest liczbą większą od 0, czy cena jest liczbą większą od 0. Jeśli którykolwiek warunek zawiedzie, wyświetl komunikat błędu (jak w sekcji 12) i przerwij dodawanie (return).
Krok 4 — dodawanie do koszyka. Jeśli dane są poprawne, dodaj nowy obiekt do tablicy koszyk (.push()), wyczyść pola formularza i wywołaj funkcję renderującą (krok 5).
Krok 5 — funkcja renderująca. Napisz rysujKoszyk(), która buduje tabelę HTML z tablicy koszyk (kolumny: produkt, ilość, cena, wartość pozycji = ilosc * cena) i wstawia ją do <div id="koszyk">. Dodaj w każdym wierszu przycisk „✕” do usuwania pozycji (analogicznie do sekcji 11).
Krok 6 — podsumowanie z rabatem. Za pomocą .reduce() policz łączną wartość koszyka. Jeśli suma przekracza 1000 zł, zastosuj rabat 10% i wyraźnie zaznacz w podsumowaniu, że rabat został naliczony (kwota przed rabatem, kwota po rabacie).
Krok 7 (dodatkowo). Dodaj sortowanie koszyka według wartości pozycji (malejąco) za pomocą dodatkowego przycisku „Sortuj wg wartości”, korzystając z .sort() i ponownego wywołania rysujKoszyk().
Gotowy szablon projektu — teraz go rozbuduj
Wszystko powyżej to pojedyncze, wyizolowane ćwiczenia. W praktyce na egzaminie dostajesz jednak jeden, kompletny projekt — stronę z formularzem, galerią i tabelą naraz — i musisz w nim coś dopisać albo poprawić. Dlatego obok tego zbioru ćwiczeń istnieje osobny, gotowy „arkusz uniwersalny”: trzy pliki (index.html, style.css, script.js), które razem tworzą działającą stronę zbudowaną w całości z semantycznego HTML5, CSS Flexbox i czystego (vanilla) JavaScriptu — bez żadnych bibliotek.
Strona ma trzy niezależne części, każda odpowiadająca innemu typowemu zadaniu z egzaminu: formularz z walidacją i zapisem do localStorage (sekcje 8, 12), interaktywną galerię z podmianą miniaturek (sekcja 9) oraz dynamiczną tabelę zbudowaną z tablicy obiektów, z wyszukiwaniem, sortowaniem, dodawaniem i usuwaniem wierszy (sekcje 10, 14, 15). Kod w script.js jest gęsto skomentowany — każda część tłumaczy krok po kroku, dlaczego wygląda tak, a nie inaczej.
index.html
style.css
script.js
Propozycje rozbudowy szablonu uniwersalnego
Tu nie ma przykładów z gotowym rozwiązaniem — to konkretne zadania do dopisania bezpośrednio w plikach szablonu, obok istniejącego, podobnego kodu. Każda z trzech części ma zadania łatwe (jedna sztuczka), średnie (łączą dwie rzeczy) i trudne (pełny, samodzielny mechanizm) — dokładnie tak, jak stopniowany bywa egzamin praktyczny.
Formularz (script.js, CZĘŚĆ 1)
Łatwe
- Dodaj walidację: pole „Imię i Nazwisko” musi mieć co najmniej 3 znaki (nie tylko „nie może być puste”).
- Dodaj pod polem tekstowym licznik znaków, aktualizowany na bieżąco podczas pisania (zdarzenie
input).
Średnie
- Dodaj nowe pole „E-mail” i sprawdź poprawność jego formatu za pomocą wyrażenia regularnego, np.
/^[^\s@]+@[^\s@]+\.[^\s@]+$/. - Zablokuj przycisk „Zatwierdź” (
disabled = true), dopóki pole tekstowe jest puste, i odblokuj, gdy coś w nim wpiszesz.
Trudne
- Zamiast zapisywać w
localStoragesamo imię, zapisz cały obiekt zgłoszenia (imię, kurs, poziom, newsletter) jako JSON (JSON.stringify/JSON.parse) i wczytaj go w całości przy starcie strony.
Galeria (script.js, CZĘŚĆ 2)
Łatwe
- Dodaj czwarte zdjęcie do galerii razem z jego miniaturką w HTML — sprawdź, że działa bez żadnych zmian w JS (kod operuje na klasie
.thumb, a nie na konkretnych ID).
Średnie
- Dodaj przyciski „Poprzednie” / „Następne”, które przechodzą po zdjęciach po kolei, bez klikania w miniaturki (podpowiedź: trzymaj w zmiennej indeks aktualnie wyświetlanego zdjęcia).
Trudne
- Dodaj automatyczne przełączanie zdjęć co 3 sekundy (
setInterval), które zatrzymuje się, gdy użytkownik najedzie myszką na galerię (mouseenter/mouseleave).
Dynamiczna tabela (script.js, CZĘŚĆ 3)
Łatwe
- Dodaj drugi przycisk sortujący — alfabetycznie po imieniu i nazwisku (przydatna metoda:
localeCompare()).
Średnie
- Zamień losowe dodawanie ucznia na prawdziwy formularz (pole tekstowe na imię + pole liczbowe na ocenę), żeby użytkownik sam wpisywał dane.
- Dodaj na dole tabeli wiersz z podsumowaniem: średnia ocen wszystkich uczniów aktualnie widocznych w tabeli.
Trudne
- Dodaj edycję oceny bezpośrednio w tabeli — kliknięcie w komórkę z oceną zamienia ją na pole
<input type="number">, a po zatwierdzeniu (np. klawiszem Enter) aktualizuje dane w tablicyuczniowie. - Zapisuj tablicę
uczniowiewlocalStoragepo każdej zmianie (dodaniu, usunięciu, edycji), żeby dane przetrwały odświeżenie strony.
To już komplet materiału
Siedemnaście sekcji: jedenaście od pierwszej zmiennej po mini-projekt z podstawami, kolejne pięć — wyróżnione czerwienią i osobnym blokiem — to zadania typowe dla egzaminu praktycznego INF.03 (walidacja, obliczenia, tablice obiektów, tabele wynikowe, projekt egzaminacyjny), a ostatnia, fioletowa sekcja to zadania rozbudowy gotowego, trójplikowego szablonu (index.html + style.css + script.js), traktowanego jako jeden, spójny projekt. Najlepiej działa to tak: przeczytaj przykład, rozwiń rozwiązanie dopiero gdy utkniesz, a zadanie obok zrób samodzielnie w konsoli przeglądarki albo w osobnym pliku .html — a zadania z ostatniej sekcji dopisz wprost do plików szablonu.