Interaktywny Konwerter Systemów Liczbowych
Zadanie 200: Interaktywny Konwerter Systemów Liczbowych
Wstęp
W powiązanym zadaniu JavaScript 200 dowiedziałeś się, jak wbudowane w JS metody toString(radix) i parseInt(string, radix) pozwalają w łatwy sposób konwertować liczby ze standardowego systemu dziesiętnego na dwójkowy (binarny), ósemkowy (oktalny) czy szesnastkowy (heksadecymalny) i z powrotem.
Jako programista Front-End, nie powinieneś jednak zostawiać swoich skryptów jedynie w konsoli. W tym zadaniu połączymy świat HTML, CSS i wyżej wymienionego skryptu JS, budując estetyczny i responsywny kalkulator działający u użytkownika na żywo z poziomu okna przeglądarki!
Cel zadania
Stwórz stronę zawierającą formularz, w którym użytkownik będzie mógł wpisać dowolną liczbę w systemie dziesiętnym, następnie z rozwijanej listy (select) wybrać docelowy system liczbowy (np. Binarny (2), Oktalny (8), Heksadecymalny (16)), po czym w trzecim, zablokowanym polu (readonly) natychmiast zobaczy sformatowany wynik. Kalkulator ma przeliczać wartości dynamicznie, w momencie ich wpisywania (bez konieczności klikania "Oblicz").
Wymagania techniczne
- Podstawowa znajomość struktury dokumentu HTML5.
- Zastosowanie formularza z etykietami (
label), wejściem na tekst (input type="text"lubtype="number"), listą wyboru (select) z opcjami (option) oraz polem tylko do odczytu (readonly). - Ostylowanie kalkulatora w CSS.
- Podpięcie zewnętrznego skryptu
.js, wyszukanie elementów w DOM przy pomocydocument.getElementByIdlubdocument.querySelector. - Użycie nasłuchiwaczy zdarzeń (
addEventListener) na akcje wejścia typuinputlub zmiany wyselekcjonowanej opcji typuchange. - Zabezpieczenie skryptu przed "NaN", czyli odpowiednia reakcja w sytuacji gdy użytkownik wpisze coś, co nie jest poprawną liczbą.
Kroki do wykonania
1. Struktura plików i dokument HTML
Utwórz folder na projekt, a w nim stwórz:
index.htmlstyle.cssscript.js
W pliku index.html utwórz szkielet HTML5 i podepnij arkusz stylów oraz skrypt zgodny ze strukturą:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Konwerter Systemów Liczbowych</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="kalkulator-container">
<h1>Kalkulator Systemów Liczbowych</h1>
<p>Wpisz liczbę dziesiętną, przelicz na wybrany system.</p>
<div class="form-group">
<label for="input-dziesietny">Wartość dziesiętna:</label>
<input type="number" id="input-dziesietny" placeholder="np. 255" autocomplete="off">
</div>
<div class="form-group">
<label for="select-system">Zamień na system:</label>
<select id="select-system">
<option value="2">Binarny (podstawa 2)</option>
<option value="8">Oktalny (podstawa 8)</option>
<option value="16">Heksadecymalny (podstawa 16)</option>
</select>
</div>
<div class="form-group">
<label for="output-wynik">Wynik konwersji:</label>
<input type="text" id="output-wynik" readonly placeholder="Wynik pojawi się tutaj">
</div>
</main>
<script src="script.js"></script>
</body>
</html>
2. Estetyczny wygląd - CSS Layout
Twój kalkulator musi dobrze wyglądać i zachęcać do użytkowania. Przejdź do style.css i wycentruj kontener np. za pomocą Flexbox.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
body {
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.kalkulator-container {
background-color: #fff;
padding: 30px;
border-radius: 12px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
width: 100%;
max-width: 400px;
}
.kalkulator-container h1 {
font-size: 20px;
margin-bottom: 10px;
text-align: center;
color: #333;
}
.kalkulator-container p {
font-size: 14px;
color: #666;
text-align: center;
margin-bottom: 25px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: bold;
color: #444;
}
.form-group input,
.form-group select {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 16px;
outline: none;
}
.form-group input:focus,
.form-group select:focus {
border-color: #007bff;
box-shadow: 0 0 5px rgba(0, 123, 255, 0.3);
}
.form-group input[readonly] {
background-color: #e9ecef;
cursor: not-allowed;
color: #0d6efd;
font-weight: bold;
}
3. Logika konwertera - plik script.js
Mając gotowy interfejs, nadeszła pora na "ożywienie" go przy pomocy logiki operującej na drzewie DOM. W klasycznym powiązaniu JS, musimy zlokalizować 3 utworzone elementy HTML (wejście liczbowe, wybierak select, i wyjście readonly), i nasłuchiwać ich interakcji.
// 1. Odszukaj elementy w drzewie DOM przy pomocy ID
const inputDziesietny = document.getElementById('input-dziesietny');
const selectSystem = document.getElementById('select-system');
const outputWynik = document.getElementById('output-wynik');
// 2. Skonstruuj funkcję konwertującą
function przelicz() {
// a) Pobierz wejściowy napis i sprawdź parsując w formę inta o bazie 10
const wartoscLiczbowa = parseInt(inputDziesietny.value, 10);
// b) Zabezpiecz NaN
if (isNaN(wartoscLiczbowa)) {
outputWynik.value = '';
return;
}
// c) Sprawdź podstawę na co zmieniamy
const systemDocelowy = parseInt(selectSystem.value, 10);
// d) Zamień bazową formę
let wynik = wartoscLiczbowa.toString(systemDocelowy);
if (systemDocelowy === 16) {
wynik = wynik.toUpperCase();
}
// e) Przepisz jako odpowiedź
outputWynik.value = wynik;
}
// 3. Nasłuchuj eventów użytkowania. Jeżeli w inpucie zajdzie event "input" wypuść trigger funkcji natychmiast
inputDziesietny.addEventListener('input', przelicz);
// Jeżeli użytkownik zmieni docelowy ustrój z listy rozwijalnej
selectSystem.addEventListener('change', przelicz);
4. Testy i weryfikacja
W przeglądarce podaj np. 255. Wynik heksadecymalny pokaże dumnie FF, binarny pokaże 11111111, zaś oktalny udowodni, że 377 ma swoją matematyczną historię.
Zadania dla chętnych
Poszerz wiedzę i postaraj się o implementację zaawansowanych zagadnień:
- Przycisk "Kopiuj do schowka": Korzystając z interfejsu przeglądarki (
navigator.clipboard.writeText) dodaj mniejszy przycisk obok wyniku, po naciśnięciu którego wynik zostaje skopiowany cicho do zwykłego systemowego schowka, wyświetlając krótki alert() lub toast UI z komunikatem. - Pełna obustronność konwersji: Dodaj po lewej select dla wejścia z którego wchodzimy, czyniąc go nie tylko "Dziesiętnym z urzędu", ale umożliwiając np wybór "Binarnego na start" a pod spodem "Heksadecymalnego". Twoja uniwersalna metoda z parseInt musi zaczerpnąć
const zSystemu = select1.value; parseInt(wartosc, zSystemu)a poniżej wynik potraktowaćtoString(select2.value). - Fiksacja Hex-ów o U2 (Ujemne): Jeśli liczysz dziesiętne liczby do 2 bez maskowania systemem ujemnym
-pozostanie na swoim wbudowanym standardzie JS. Poszukaj na StackOverflow jak zbudować odpowiednią bramkę bitową wypisując bezmyślnie "zera po lewej", lub w prostszym przypadku obsłuż ujemne liczby do formatu u2 jeśli użytkownik z listy rozwijanej chciał by to uaktywnić odpowiednim Checkboxem.