Kurs JavaScript z przykładami
Przygotowanie do egzaminu zawodowego INF.03 — tworzenie stron i aplikacji internetowych. Każdy temat zawiera teorię, przykład z rozwiązaniem oraz propozycję podobnego zadania egzaminacyjnego z ukrytą odpowiedzią.
Jak osadzić JavaScript w HTML
PodstawyKod JavaScript uruchamiamy zawsze wewnątrz elementu <script>. Można go osadzić na dwa sposoby: wewnętrznie (bezpośrednio w pliku HTML) oraz zewnętrznie (w osobnym pliku .js dołączanym atrybutem src).
Skrypt wewnętrzny umieszczamy między znacznikami <script> ... </script>. Skrypt zewnętrzny podłączamy pustym znacznikiem: <script src="skrypt.js"></script> — kod trzymamy wtedy w osobnym pliku, co jest zalecane w większych projektach i na egzaminie INF.03.
Znacznik <script> najlepiej wstawiać tuż przed zamknięciem </body> albo dodać atrybut defer w sekcji <head>. Dzięki temu kod uruchomi się dopiero po wczytaniu elementów HTML i nie zgłosi błędu „null”.
Zaletą pliku zewnętrznego jest oddzielenie treści (HTML) od logiki (JS), możliwość ponownego użycia tego samego skryptu na wielu stronach oraz łatwiejsze utrzymanie kodu.
Przykład
Skrypt wewnętrzny (inline) — cały kod JavaScript znajduje się w pliku HTML.
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8" />
<title>Skrypt wewnetrzny</title>
</head>
<body>
<h1 id="tytul">Strona</h1>
<!-- skrypt tuz przed </body>, gdy HTML jest juz wczytany -->
<script>
const tytul = document.getElementById("tytul")
tytul.textContent = "Zmieniono przez JavaScript"
console.log("Skrypt wewnetrzny dziala")
</script>
</body>
</html>Rozwiązanie / wariant
Skrypt zewnętrzny — kod przenosimy do pliku skrypt.js i dołączamy atrybutem src. Atrybut defer w sekcji head gwarantuje, że skrypt wykona się po wczytaniu strony.
<!-- plik: index.html -->
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8" />
<title>Skrypt zewnetrzny</title>
<!-- defer: skrypt uruchomi sie po zbudowaniu strony -->
<script src="skrypt.js" defer></script>
</head>
<body>
<h1 id="tytul">Strona</h1>
</body>
</html>
/* plik: skrypt.js */
const tytul = document.getElementById("tytul")
tytul.textContent = "Tekst z pliku zewnetrznego"
console.log("Skrypt zewnetrzny dziala")- Utwórz stronę HTML z akapitem <p id="data"></p>.
- W osobnym pliku app.js (dołączonym do strony) wpisz do tego akapitu aktualny rok.
- Zadbaj o to, aby skrypt uruchomił się dopiero po wczytaniu elementu (użyj defer lub umieść znacznik przed </body>).
▶Pokaż rozwiązanie
<!-- plik: index.html -->
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8" />
<title>Zadanie</title>
<script src="app.js" defer></script>
</head>
<body>
<p id="data"></p>
</body>
</html>
/* plik: app.js */
const akapit = document.getElementById("data")
akapit.textContent = "Aktualny rok: " + new Date().getFullYear()Wskazówka: Bez atrybutu defer skrypt w sekcji <head> wykona się, zanim powstanie <p id="data"> — getElementById zwróci wtedy null i wystąpi błąd.
Zmienne i typy danych
PodstawyW JavaScript zmienne deklarujemy słowami kluczowymi let (wartość zmienna), const (stała) oraz var (starszy zapis, którego unikamy).
Podstawowe typy danych to: string (tekst), number (liczba), boolean (prawda/fałsz), null, undefined oraz object.
Typ zmiennej sprawdzimy operatorem typeof. JavaScript jest językiem o typowaniu dynamicznym — typ ustalany jest w trakcie działania programu.
Przykład
Zadeklaruj dane ucznia i wypisz je w konsoli wraz z ich typami.
const imie = "Anna"
let wiek = 18
const czyPelnoletni = wiek >= 18
console.log(imie, typeof imie) // Anna string
console.log(wiek, typeof wiek) // 18 number
console.log(czyPelnoletni, typeof czyPelnoletni) // true booleanRozwiązanie / wariant
Łączymy tekst z wartościami zmiennych za pomocą szablonów tekstowych (backtick), co jest czytelniejsze niż sklejanie plusem.
const imie = "Anna"
const wiek = 18
const komunikat = `Uczen ${imie} ma ${wiek} lat.`
console.log(komunikat) // Uczen Anna ma 18 lat.- Utwórz trzy stałe przechowujące: nazwę produktu (tekst), cenę netto (liczba) oraz stawkę VAT równą 0.23.
- Oblicz cenę brutto i wypisz w konsoli komunikat w formacie: „Produkt X kosztuje brutto Y zł”.
▶Pokaż rozwiązanie
const nazwa = "Klawiatura"
const cenaNetto = 120
const vat = 0.23
const cenaBrutto = cenaNetto * (1 + vat)
console.log(`Produkt ${nazwa} kosztuje brutto ${cenaBrutto} zl`)
// Produkt Klawiatura kosztuje brutto 147.6 zlWskazówka: Do zaokrąglenia do 2 miejsc użyj cenaBrutto.toFixed(2).
Instrukcje warunkowe
PodstawyInstrukcja if / else if / else pozwala wykonać kod zależnie od spełnienia warunku.
Operatory porównania: === (równe i tego samego typu), !== , >, <, >=, <=. Zawsze preferuj === zamiast ==.
Operatory logiczne: && (i), || (lub), ! (negacja). Do wielu wariantów jednej zmiennej wygodny jest switch.
Przykład
Na podstawie liczby punktów ustal ocenę.
const punkty = 75
if (punkty >= 90) {
console.log("Ocena: 5")
} else if (punkty >= 75) {
console.log("Ocena: 4")
} else if (punkty >= 50) {
console.log("Ocena: 3")
} else {
console.log("Ocena: 2")
}
// Ocena: 4Rozwiązanie / wariant
Ten sam problem można zapisać operatorem trójargumentowym, gdy wariantów jest niewiele.
const wiek = 16
const bilet = wiek < 18 ? "ulgowy" : "normalny"
console.log(`Bilet: ${bilet}`) // Bilet: ulgowy- Napisz kod, który dla zmiennej liczba sprawdzi, czy jest ona dodatnia, ujemna czy równa zero.
- Dodatkowo poinformuj, czy liczba jest parzysta czy nieparzysta.
▶Pokaż rozwiązanie
const liczba = -8
if (liczba > 0) console.log("Liczba dodatnia")
else if (liczba < 0) console.log("Liczba ujemna")
else console.log("Liczba rowna zero")
console.log(liczba % 2 === 0 ? "Parzysta" : "Nieparzysta")
// Liczba ujemna
// ParzystaWskazówka: Parzystość sprawdzamy resztą z dzielenia: liczba % 2 === 0.
Pętle
PodstawyPętla for służy do powtarzania kodu znaną liczbę razy. Ma trzy części: inicjalizację, warunek i zmianę licznika.
Pętla while wykonuje kod, dopóki warunek jest prawdziwy — używamy jej, gdy nie znamy z góry liczby powtórzeń.
Instrukcja break przerywa pętlę, a continue pomija bieżącą iterację.
Przykład
Wypisz liczby od 1 do 5 oraz ich sumę.
let suma = 0
for (let i = 1; i <= 5; i++) {
console.log(i)
suma += i
}
console.log("Suma:", suma) // Suma: 15Rozwiązanie / wariant
Wersja z pętlą while działa identycznie — sami sterujemy licznikiem.
let i = 1
let suma = 0
while (i <= 5) {
suma += i
i++
}
console.log("Suma:", suma) // Suma: 15- Za pomocą pętli wypisz tabliczkę mnożenia liczby 7 (od 7×1 do 7×10).
- Każdy wynik wyświetl w formacie: „7 x n = wynik”.
▶Pokaż rozwiązanie
for (let n = 1; n <= 10; n++) {
console.log(`7 x ${n} = ${7 * n}`)
}
// 7 x 1 = 7
// 7 x 2 = 14
// ...
// 7 x 10 = 70Wskazówka: Licznik n pełni rolę mnożnika — mnóż go przez 7 w każdej iteracji.
Funkcje
ŚrednioFunkcja to nazwany blok kodu, który można wielokrotnie wywoływać. Może przyjmować parametry i zwracać wartość słowem return.
Funkcje strzałkowe (arrow functions) to krótszy zapis: const nazwa = (a, b) => a + b.
Dzielenie programu na funkcje poprawia czytelność i pozwala unikać powtarzania kodu (zasada DRY).
Przykład
Funkcja obliczająca pole prostokąta.
function poleProstokata(a, b) {
return a * b
}
console.log(poleProstokata(4, 5)) // 20
console.log(poleProstokata(3, 7)) // 21Rozwiązanie / wariant
Ta sama funkcja w zapisie strzałkowym, z domyślną wartością parametru.
const poleKwadratu = (a = 1) => a * a
console.log(poleKwadratu(5)) // 25
console.log(poleKwadratu()) // 1 (uzyto wartosci domyslnej)- Napisz funkcję najwiekszaZ(a, b, c), która zwróci największą z trzech przekazanych liczb.
- Przetestuj ją na trzech różnych zestawach danych.
▶Pokaż rozwiązanie
function najwiekszaZ(a, b, c) {
return Math.max(a, b, c)
}
console.log(najwiekszaZ(3, 9, 5)) // 9
console.log(najwiekszaZ(12, 4, 8)) // 12
console.log(najwiekszaZ(-1, -7, -3)) // -1Wskazówka: Wbudowana funkcja Math.max() zwraca największą z podanych liczb.
Tablice
ŚrednioTablica przechowuje listę wartości pod jedną nazwą. Do elementów odwołujemy się przez indeks liczony od 0.
Przydatne metody: push (dodaj na koniec), pop (usuń ostatni), length (liczba elementów), includes (czy zawiera).
Metody wyższego rzędu: map (przekształć), filter (odfiltruj), reduce (zredukuj do jednej wartości).
Przykład
Przejdź po tablicy ocen i policz ich sumę.
const oceny = [3, 4, 5, 2, 4]
let suma = 0
for (let i = 0; i < oceny.length; i++) {
suma += oceny[i]
}
console.log("Suma ocen:", suma) // Suma ocen: 18Rozwiązanie / wariant
Średnią policzymy krócej metodą reduce.
const oceny = [3, 4, 5, 2, 4]
const suma = oceny.reduce((acc, o) => acc + o, 0)
const srednia = suma / oceny.length
console.log(`Srednia: ${srednia.toFixed(2)}`) // Srednia: 3.60- Mając tablicę liczb, utwórz nową tablicę zawierającą wyłącznie liczby parzyste.
- Wypisz obie tablice oraz liczbę elementów w tablicy wynikowej.
▶Pokaż rozwiązanie
const liczby = [5, 8, 3, 12, 7, 20, 15]
const parzyste = liczby.filter((n) => n % 2 === 0)
console.log("Wszystkie:", liczby)
console.log("Parzyste:", parzyste) // [8, 12, 20]
console.log("Ilosc:", parzyste.length) // 3Wskazówka: Metoda filter tworzy nową tablicę z elementów spełniających warunek.
Obiekty
ŚrednioObiekt grupuje powiązane dane w postaci par klucz: wartość. Do właściwości odwołujemy się kropką (obiekt.klucz) lub nawiasem (obiekt['klucz']).
Obiekt może zawierać metody, czyli funkcje będące jego właściwościami.
Tablica obiektów to typowa struktura do przechowywania listy rekordów, np. produktów czy uczniów.
Przykład
Utwórz obiekt opisujący ucznia z metodą przedstawiającą go.
const uczen = {
imie: "Marek",
klasa: "3A",
przedstaw() {
return `${this.imie} z klasy ${this.klasa}`
},
}
console.log(uczen.imie) // Marek
console.log(uczen.przedstaw()) // Marek z klasy 3ARozwiązanie / wariant
Po tablicy obiektów iterujemy pętlą for...of.
const produkty = [
{ nazwa: "Mysz", cena: 50 },
{ nazwa: "Monitor", cena: 800 },
]
for (const p of produkty) {
console.log(`${p.nazwa}: ${p.cena} zl`)
}
// Mysz: 50 zl
// Monitor: 800 zl- Utwórz tablicę obiektów reprezentujących produkty (nazwa, cena, ilość).
- Oblicz łączną wartość magazynu (suma cena × ilość dla wszystkich produktów).
▶Pokaż rozwiązanie
const magazyn = [
{ nazwa: "Kabel", cena: 10, ilosc: 5 },
{ nazwa: "Router", cena: 200, ilosc: 3 },
{ nazwa: "Switch", cena: 350, ilosc: 2 },
]
const wartosc = magazyn.reduce((suma, p) => suma + p.cena * p.ilosc, 0)
console.log("Wartosc magazynu:", wartosc, "zl") // 1350 zlWskazówka: W reduce dodawaj do akumulatora iloczyn p.cena * p.ilosc.
Manipulacja DOM
ZaawansowaneDOM to drzewiasta reprezentacja strony HTML, którą JavaScript może odczytywać i zmieniać.
Elementy pobieramy metodami: document.getElementById('id') lub document.querySelector('selektor CSS').
Zawartość zmieniamy przez textContent (sam tekst) lub innerHTML (kod HTML). Style zmieniamy przez element.style lub classList.
Przykład
Zmień treść nagłówka i kolor akapitu (kod działa na stronie z tymi elementami).
const naglowek = document.getElementById("tytul")
naglowek.textContent = "Nowy tytul strony"
const akapit = document.querySelector(".opis")
akapit.style.color = "green"Rozwiązanie / wariant
Dodawanie nowych elementów do listy w DOM.
const lista = document.querySelector("#lista")
const owoce = ["jablko", "gruszka", "sliwka"]
owoce.forEach((owoc) => {
const li = document.createElement("li")
li.textContent = owoc
lista.appendChild(li)
})- Na stronie znajduje się element <p id="licznik">0</p> oraz przycisk.
- Napisz kod, który po naciśnięciu przycisku zwiększa liczbę wyświetloną w akapicie o 1.
▶Pokaż rozwiązanie
const licznik = document.getElementById("licznik")
const przycisk = document.getElementById("dodaj")
przycisk.addEventListener("click", () => {
licznik.textContent = Number(licznik.textContent) + 1
})Wskazówka: textContent zwraca tekst — zamień go na liczbę funkcją Number() przed dodawaniem.
Obsługa zdarzeń
ZaawansowaneZdarzenia to reakcje na działania użytkownika: kliknięcie (click), najechanie (mouseover), wpisanie tekstu (input), wysłanie formularza (submit).
Nasłuchiwanie zdarzeń dodajemy metodą element.addEventListener('typ', funkcja).
Funkcja obsługi otrzymuje obiekt zdarzenia (event), z którego odczytamy np. wciśnięty klawisz lub element źródłowy.
Przykład
Reaguj na kliknięcie przycisku.
const przycisk = document.querySelector("#klik")
przycisk.addEventListener("click", () => {
alert("Kliknieto przycisk!")
})Rozwiązanie / wariant
Odczyt tekstu wpisywanego w polu na żywo zdarzeniem input.
const pole = document.querySelector("#imie")
const wynik = document.querySelector("#powitanie")
pole.addEventListener("input", (e) => {
wynik.textContent = `Witaj, ${e.target.value}!`
})- Na stronie jest przycisk „Zmień tło”.
- Napisz kod, który przy każdym kliknięciu przełącza kolor tła strony między białym a jasnoszarym.
▶Pokaż rozwiązanie
const przycisk = document.getElementById("zmienTlo")
let jasne = true
przycisk.addEventListener("click", () => {
document.body.style.backgroundColor = jasne ? "#e5e5e5" : "#ffffff"
jasne = !jasne
})Wskazówka: Przechowuj stan w zmiennej boolean i odwracaj ją operatorem ! przy każdym kliknięciu.
Walidacja formularzy
ZaawansowaneFormularze wysyłają dane — zdarzenie submit warto przechwycić i zablokować przeładowanie strony metodą event.preventDefault().
Wartości pól odczytujemy przez element.value. Sprawdzamy, czy nie są puste oraz czy mają poprawny format.
Do walidacji formatu (np. e-mail) używamy metody .includes(), porównań długości lub wyrażeń regularnych.
Przykład
Zablokuj wysłanie formularza, jeśli pole jest puste.
const form = document.querySelector("#formularz")
const login = document.querySelector("#login")
form.addEventListener("submit", (e) => {
e.preventDefault()
if (login.value === "") {
alert("Podaj login!")
} else {
alert("Formularz wyslany")
}
})Rozwiązanie / wariant
Walidacja adresu e-mail i długości hasła z wyświetleniem komunikatu na stronie.
const email = document.querySelector("#email")
const haslo = document.querySelector("#haslo")
const info = document.querySelector("#info")
function sprawdz() {
if (!email.value.includes("@")) {
info.textContent = "Niepoprawny e-mail"
} else if (haslo.value.length < 8) {
info.textContent = "Haslo min. 8 znakow"
} else {
info.textContent = "Dane poprawne"
}
}- Formularz zawiera pole „wiek”.
- Po wysłaniu sprawdź, czy podano liczbę z zakresu 1–120. Wyświetl odpowiedni komunikat w elemencie o id „komunikat”.
▶Pokaż rozwiązanie
const form = document.getElementById("form")
const wiek = document.getElementById("wiek")
const komunikat = document.getElementById("komunikat")
form.addEventListener("submit", (e) => {
e.preventDefault()
const w = Number(wiek.value)
if (Number.isNaN(w) || w < 1 || w > 120) {
komunikat.textContent = "Podaj wiek z zakresu 1-120"
} else {
komunikat.textContent = "Wiek poprawny: " + w
}
})Wskazówka: Number.isNaN() wykryje, że pole nie zawiera liczby.
Data i localStorage
ZaawansowaneObiekt Date reprezentuje datę i czas. new Date() zwraca aktualny moment, a metody getFullYear(), getMonth(), getDate() jego części.
localStorage pozwala trwale zapisać dane w przeglądarce (jako tekst): setItem(klucz, wartosc), getItem(klucz), removeItem(klucz).
Do zapisu obiektów w localStorage konwertujemy je metodą JSON.stringify, a przy odczycie JSON.parse.
Przykład
Wyświetl aktualną datę w formacie dzień-miesiąc-rok.
const dzis = new Date()
const d = dzis.getDate()
const m = dzis.getMonth() + 1 // miesiace liczone od 0
const r = dzis.getFullYear()
console.log(`${d}-${m}-${r}`) // np. 11-9-2026Rozwiązanie / wariant
Zapis i odczyt danych z localStorage.
// zapis
localStorage.setItem("nick", "admin")
// odczyt
const nick = localStorage.getItem("nick")
console.log(nick) // admin
// zapis obiektu
const ustawienia = { motyw: "ciemny", jezyk: "pl" }
localStorage.setItem("ust", JSON.stringify(ustawienia))
const odczyt = JSON.parse(localStorage.getItem("ust"))
console.log(odczyt.motyw) // ciemny- Napisz licznik odwiedzin strony.
- Przy każdym załadowaniu strony zwiększ zapisaną w localStorage liczbę odwiedzin o 1 i wyświetl ją w konsoli.
▶Pokaż rozwiązanie
let odwiedziny = Number(localStorage.getItem("odwiedziny")) || 0
odwiedziny++
localStorage.setItem("odwiedziny", odwiedziny)
console.log("Liczba odwiedzin:", odwiedziny)Wskazówka: getItem zwraca null przy pierwszym wejściu — użyj || 0, aby zacząć od zera.