Materiał edukacyjny · Informatyka JavaScript w przeglądarce · Moduł 14

MODUŁ 14

Próba przekrojowa i diagnostyka błędów

PPrezentacja dla nauczyciela

W ostatnim module zbieramy wszystkie zdobyte umiejętności w spójną całość. Poznasz sprawdzoną metodykę rozwiązywania zadań praktycznych krok po kroku: od wypisania danych wejściowych, przez szybką diagnostykę błędów w konsoli, po stworzenie kompletnego, działającego konfiguratora.

Metodyka pracy i analiza wymagań skryptu

Sukces przy tworzeniu skryptów przeglądarkowych opiera się na zdyscyplinowanej i powtarzalnej metodyce pracy. Zamiast pisać od razu cały, rozbudowany program, warto podzielić realizację na cztery przejrzyste etapy:

  1. Identyfikacja wejść i wyjść: Wypisz wszystkie elementy formularza, z których skrypt będzie czytać dane, oraz elementy DOM, w których wyświetlisz wyniki. Sprawdź ich atrybuty id bezpośrednio w kodzie HTML, aby wykluczyć literówki.
  2. Zbudowanie szkieletu: Napisz minimalną działającą funkcję: odczytaj wartość, wykonaj proste działanie i wypisz wynik do wskazanego akapitu. Uruchom skrypt i upewnij się, że podłączenie działa.
  3. Implementacja warunków i szczegółów: Dodaj naliczanie rabatów, sprawdzanie pól wyboru oraz walidację danych wejściowych.
  4. Weryfikacja przypadków testowych: Przetestuj działanie skryptu dla przypadku typowego, wartości granicznych (np. dokładnie na progu rabatowym) oraz przy błędnych lub pustych danych wejściowych.
function przeliczPizze() {
  const rozmiarCena = Number(document.getElementById('rozmiarPizzy').value);
  const kodPromo = document.getElementById('kodPromo').value.trim().toUpperCase();
  const czyDostawa = document.getElementById('opcjaDostawa').checked;
  const wynik = document.getElementById('podsumowaniePizzy');

  let koszt = rozmiarCena;

  if (czyDostawa) {
    koszt += 8;
  }

  if (kodPromo === 'PIZZA10') {
    koszt = koszt * 0.90;
    wynik.textContent = 'Cena po rabacie: ' + koszt.toFixed(2) + ' zł (kod aktywny)';
  } else {
    wynik.textContent = 'Do zapłaty: ' + koszt.toFixed(2) + ' zł';
  }
}
1. Jaki jest zalecany pierwszy krok podczas implementacji skryptu na podstawie specyfikacji zadania?
2. Dlaczego warto implementować i testować skrypt w małych, działających przyrostach zamiast pisać cały kod naraz?
3. Które przypadki testowe należy bezwzględnie sprawdzić po ukończeniu implementacji logiki?

Diagnozowanie błędów i praca z konsolą

Gdy strona nie reaguje na kliknięcie przycisku lub wyświetla nieoczekiwane wyniki, pierwszym miejscem inspekcji powinna być zawsze konsola narzędzi deweloperskich przeglądarki (skrót klawiszowy F12 lub Ctrl + Shift + I).

Najczęstsze błędy i ich przyczyny:

  • TypeError: Cannot read properties of null (reading 'value') — metoda getElementById() zwróciła null. Oznacza to literówkę w identyfikatorze, brak elementu w kodzie HTML lub próbę odpytania DOM przed jego załadowaniem.
  • Niezamierzone sklejenie tekstu zamiast dodawania (np. "50" + "20" = "5020") — brak jawnej konwersji za pomocą Number().
  • Sprawdzanie stanu checkboxa przez pole.value zamiast właściwości pole.checked.
  • ReferenceError: nazwaFunkcji is not defined — literówka w nazwie funkcji w atrybucie onclick lub niepodłączony plik <script src="...">.

Do śledzenia wartości zmiennych w trakcie działania skryptu używaj metody console.log('Wartość:', zmienna). Po poprawieniu kodu w pliku zawsze odśwież stronę w przeglądarce przed ponownym testem.

function diagnozujIKalkuluj() {
  const poleLokaty = document.getElementById('kwotaLokaty');
  const poleProcent = document.getElementById('procentRoczny');
  const wynik = document.getElementById('wynikOdsetek');

  console.log('Sprawdzanie pól formularza:', poleLokaty, poleProcent);

  if (!poleLokaty || !poleProcent) {
    console.error('Błąd: nie znaleziono elementów formularza w drzewie DOM!');
    return;
  }

  const kwota = Number(poleLokaty.value);
  const procent = Number(poleProcent.value);

  console.log('Pobrane wartości liczbowe:', { kwota: kwota, procent: procent });

  if (isNaN(kwota) || kwota <= 0 || isNaN(procent) || procent <= 0) {
    wynik.textContent = 'Błąd: podaj poprawne wartości liczbowe większe od zera.';
    wynik.style.color = '#dc2626';
    return;
  }

  const zysk = kwota * (procent / 100);
  console.log('Wyliczony roczny zysk:', zysk);

  wynik.textContent = 'Roczny zysk z lokaty: ' + zysk.toFixed(2) + ' zł';
  wynik.style.color = '#16a34a';
}
4. Co najczęściej oznacza komunikat błędu TypeError: Cannot read properties of null w konsoli przeglądarki?
5. Jakie narzędzie w konsoli deweloperskiej pozwala na bieżąco sprawdzić wartości zmiennych w trakcie działania funkcji?
6. Dlaczego po poprawieniu błędu w pliku skryptu na dysku należy odświeżyć stronę w przeglądarce przed ponownym testem?

Kompleksowa integracja formularza i interfejsu

Praktyczne zadania ze skryptów przeglądarkowych rzadko ograniczają się do jednego elementu. Zwykle wymagają skoordynowania kilku kontrolek różnych typów: listy rozwijanej, przycisków radiowych, pól wyboru oraz pól tekstowych z walidacją obecności danych.

Kompletny skrypt realizuje następujący ciąg operacji:

  • Pobiera i weryfikuje dane klienta — w razie pustego pola wyświetla ostrzeżenie (np. przez alert()) i natychmiast przerywa działanie instrukcją return,
  • Pobiera cenę bazową wybranej opcji z elementu <select>,
  • Odczytuje wartość zaznaczonego przycisku radiowego za pomocą selektora :checked,
  • Sprawdza stan dodatkowych pól typu checkbox za pomocą właściwości checked i dolicza opcjonalne koszty,
  • Formatuje łączną sumę metodą .toFixed(2) i wpisuje szczegółowe podsumowanie do wskazanego elementu DOM.
function finalizujKonfiguracje() {
  const imie = document.getElementById('klientImie').value.trim();
  const podsumowanie = document.getElementById('podsumowanieZestawu');

  if (imie === '') {
    alert('Błąd: Podaj imię zamawiającego!');
    podsumowanie.textContent = 'Proszę uzupełnić brakujące imię klienta.';
    podsumowanie.style.color = '#dc2626';
    return;
  }

  const cenaProcesora = Number(document.getElementById('procesorSelect').value);
  const zaznaczonyRam = document.querySelector('input[name="ramWybor"]:checked');
  const cenaRam = Number(zaznaczonyRam.value);
  const montaz = document.getElementById('montazSprzetu');

  let razem = cenaProcesora + cenaRam;

  if (montaz.checked) {
    razem += Number(montaz.value);
  }

  alert('Dziękujemy ' + imie + '! Zamówienie zostało zarejestrowane.');

  podsumowanie.innerHTML = 'Klient: ' + imie + '
' + 'Koszt zestawu: ' + razem.toFixed(2) + ' zł (w tym montaż: ' + (montaz.checked ? 'TAK' : 'NIE') + ')'; podsumowanie.style.color = '#16a34a'; }
7. W jaki sposób zabezpieczyć kompleksowy kalkulator przed błędnym wejściem z pola imię klienta?
8. Co jest najlepszą praktyką, gdy zadanie wymaga pobrania danych z kilku różnych typów kontrolek (select, radio, checkbox)?
9. Jaki jest cel sformatowania końcowej wyceny zamówienia za pomocą kwota.toFixed(2)?

Ćwiczenia