
Zaczynamy wreszcie praktyczne kodowanie! W poprzednim wpisie poznaliśmy trochę teorii i historii, a teraz przechodzimy do działania. Będziemy budować małą funkcjonalność na naszej stronie z przepisami – to lista zakupów, którą użytkownik może tworzyć bezpośrednio przy czytaniu przepisu. Ten wpis posłuży za przygotowanie projektu: zrobimy setup plików i dodamy niezbędny kod HTML, ale jeszcze bez wgłębiania się w skomplikowaną składnię JavaScript. Wszystko krok po kroku, na luzie i konkretnie. Wszystko jasne? No to zaczynamy!
Spis treści
- Cel aplikacji lista zakupów
- Dlaczego to ma sens?
- Technikalia
- Mam HTML i CSS, a gdzie pisać JS?
- Jak dodać JavaScript do strony?
- Co to jest defer?
- HTML – co dodajemy do aside?
- Ćwiczenia
- Lista zakupów – efekty
- Bonus – lista zakupów a dostępność
Cel aplikacji lista zakupów
Co dokładnie budujemy? Listę zakupów w bocznej kolumnie strony <aside>
, tuż pod sekcją „Info”. Wyobraź sobie, że przeglądasz przepis kulinarny na naszej stronie. Obok, w panelu informacyjnym, możesz od razu wypisywać produkty, które musisz kupić, by ten przepis zrealizować. Aplikacja ma umożliwić dodawanie składników do listy (np. „2 banany”, „1 litr mleka”) i wyświetlać je poniżej, tak abyś mógł łatwo wykorzystać tę listę podczas zakupów. Dzięki temu użytkownik nie musi już szukać kartki ani przełączać się między aplikacjami – wszystko jest pod ręką na stronie z przepisem.
Dlaczego to ma sens?
Zamiast pisać nudny opis biznesowy, podejdźmy do tematu z perspektywy użytkownika, czyli w formie user story (historyjki użytkownika). Jeśli nie spotkałeś się z tym pojęciem: to prosty, jednozdaniowy opis funkcji z punktu widzenia osoby, która będzie z niej korzystać. Często używa się przy tym schematu:
„Jako [rola użytkownika] chcę [osiągnąć cel], aby [motywacja/korzyść]”.
Brzmi poważnie, ale jest bardzo przydatne w planowaniu funkcjonalności.
Spróbujmy tak opisać naszą listę zakupów. User story dla tej funkcji mogłaby brzmieć następująco: „Jako użytkownik czytający przepis chcę dodać potrzebne składniki do listy zakupów na stronie, aby łatwo sprawdzić w sklepie, co mam kupić.” Czy to nie oddaje sedna? Dzięki takiej historyjce od razu widać, po co robimy tę funkcję: ma ułatwić życie czytelnikowi przepisu. Zamiast myśleć „bo fajnie mieć listę zakupów”, formułujemy konkretną potrzebę i wartość, jaką ta lista daje. To podejście pomaga nam – programistom – skupić się na tym, co ważne dla użytkownika. Warto wiedzieć, że z tej metody projektowania funkcjonalności korzysta się profesjonalnie w zespołach projektowych.
Technikalia
Jak już opisałam w poprzednim wpisie, podczas dodawania listy zakupów do strony będziemy się opierać na makietach zawartych tutaj. Makiety obejmują urządzenia mobilne (telefony) oraz komputery (desktop). Nie uwzględniałam widoków na tablet, ponieważ te rozdzielczości wyświetlają menu boczne w identyczny sposób bo komputery.


Pliki z wyjściowych kodem ukończonym w moim kursie HTML i CSS znajdziesz w tym miejscu. Kod najprościej możesz pobrać klikając w przycisk Code i wybierając opcję Download ZIP. Po rozpakowaniu i otwarciu folderu w edytorze zobaczysz wszystkie pliki z paczki.

Jeśli korzystanie z edytora i kontroli wersji sprawia Ci trudność, odsyłam Cię do moich wpisów na temat instalacji i korzystania z darmowego edytora kodu Visual Studio Code oraz instrukcji korzystania z systemu kontroli wersji GIT.
Jak pisałam wcześniej, cale repozytorium zostało tak pomyślane, aby zrealizowane zmiany po każdej lekcji były dostępne na konkretnym branchu (gałęzi kodu). Zdecydowałam się na takie rozwiązanie po to, aby możliwe było porównanie zmian zachodzących pomiędzy lekcjami. Pod koniec tej części otrzymasz link do brancha, gdzie znajdziesz pliki ze zmianami omówionymi w tym wpisie.
Mam HTML i CSS, a gdzie pisać JS?
Jeśli czytałeś mój wpis poświęcony CSSowi (lub masz doświadczenie w pisaniu stron), to wiesz że style możesz „na upartego” pisać w pliku HTML. W ten sam sposób można pisać kod JavaScript. Jeśli chcesz tylko coś przetestować albo robisz szybki szkic, czasem łatwiej dodać <script>
na dole HTML-a i wrzucić tam kilka linijek kodu. Działa? Działa. Ale na dłuższą metę zaczyna się robić bałagan.
Znacznie lepszym rozwiązaniem jest trzymanie JavaScriptu osobno. Plik .js
zapewnia większy porządek – HTML to struktura elementów, CSS dba o wygląd, a JS odpowiada za interaktywność. Każda część robi swoje, nie miesza się z resztą i łatwiej to ogarnąć. No i jak chcesz coś poprawić, to wiesz, gdzie szukać. Bez scrollowania po kilometrze kodu.
W tym kursie trzymamy cały JavaScript w osobnym pliku script.js
. Podpinamy go na górze strony, w sekcji <head>
dokumentu, i tam będziemy działać. Przejrzyście, wygodnie i zgodnie ze sztuką.
Jak dodać JavaScript do strony?
Zanim napiszemy choć linię kodu obsługującego naszą listę zakupów, musimy upewnić się, że JavaScript jest podłączony do naszej strony. Wykonaj poniższe kroki, aby przygotować środowisko:
- Utwórz plik
script.js
– Otwórz swój edytor kodu i stwórz nowy plik o nazwiescript.js
. Zapisz go w folderze projektu, tam gdzie znajduje się Twój plik HTML (np.index.html
). To w tym pliku będziemy pisać cały kod JavaScript naszej aplikacji. - Dołącz plik do HTML – Teraz połączmy ten plik ze stroną. Otwórz plik HTML i dodaj element
<script>
w sekcji<head>
pliku HTML, np. pod linkiem do arkusza stylów CSS. Kod, który dodajesz, powinien wyglądać tak:<script defer src="script.js"></script>
Upewnij się, że atrybutsrc
wskazuje dokładnie na nazwę i lokalizację Twojego pliku. Jeśli wszystko zrobisz poprawnie, przeglądarka wczytascript.js
automatycznie przy otwieraniu strony. - Pierwszy test –
console.log
– Czas sprawdzić, czy nasz skrypt faktycznie się ładuje. W plikuscript.js
napisz coś prostego, np.:console.log('Skrypt podłączony!');
i zapisz plik. To polecenie wyświetli komunikat w konsoli przeglądarki. Nie zobaczysz go na stronie, ale zaraz pokażę Ci, gdzie szukać wyniku. - Odpal konsolę w przeglądarce – Otwórz swoją stronę HTML w przeglądarce (plik
index.html
). Teraz uruchom narzędzia deweloperskie – w Chrome zrobisz to naciskając F12 lub kombinację Ctrl+Shift+I (Windows/Linux) lub Cmd+Option+I (Mac). Powinno pojawić się okienko z różnymi zakładkami; wybierz zakładkę Console (Konsola). Jeśli wszystko poszło dobrze, po odświeżeniu strony zobaczysz tam tekst, który podałeś wconsole.log
. Brawo! Właśnie dodałeś JavaScript do strony i wykonałeś pierwszy kod. Teraz mamy pewność, że nasze środowisko działa poprawnie.
Na tym etapie mamy gotowy setup – plik script.js
jest zaimportowany do strony, a my potwierdziliśmy jego działanie prostym logiem w konsoli. Możemy więc przejść do kolejnych kroków, czyli napisania HTML-a dla naszej funkcji i (wkrótce) samej logiki w JavaScript.
Co to jest defer?
Jak możesz zauważyć, w elemencie <script>
w pliku HTML dopisałam słowo defer
. Czy wiesz do czego ono służy?
Gdy dodajesz <script src="...">
do strony, przeglądarka zatrzymuje ładowanie HTML-a, żeby najpierw pobrać i wykonać ten skrypt. Trochę jak: „stop, najpierw zajmiemy się plikiem JS, potem resztą”. Jeśli taki skrypt masz gdzieś wysoko w kodzie, może to opóźnić wczytanie reszty strony. Dlatego powszechnie korzysta się z atrybutów, które zmieniają sposób działania przeglądarki: async
i defer
.
Atrybut async
pobiera skrypt w tle i odpala go, jak tylko będzie gotowy – nie czeka, nie patrzy, czy HTML już się załadował. Nadaje się do wrzucania np. Google Analytics, ale jeśli skrypt korzysta z elementów HTML, które jeszcze nie istnieją – robi się problem. Natomiast defer
działa trochę inaczej: też ładuje plik równolegle, ale uruchamia go dopiero, gdy cały dokument HTML jest już gotowy. I to jest właśnie to, czego potrzebujemy przy takich rzeczach jak lista zakupów – albo wrzucamy <script>
na sam dół strony, albo dodajemy defer
w <head>
i mamy spokój.
HTML – co dodajemy do aside?
Skoro celem jest wyświetlanie listy zakupów w bocznej kolumnie, musimy dodać odpowiednie elementy HTML do sekcji <aside>
naszej strony. W poprzednich częściach kursu zbudowaliśmy już strukturę HTML – w <aside>
mamy nagłówek „Info” i np. sekcję z informacją o autorze oraz listą linków. Teraz dodamy tam kolejną część przeznaczoną na listę zakupów.
Otwórz plik HTML i znajdź miejsce, gdzie znajduje się <aside> ... </aside>
. Dodaj w środku taki fragment kodu:
<article>
<h3>lista zakupów:</h3>
<form>
<input type="text" placeholder="np. 2 banany" />
<button type="submit">Dodaj</button>
</form>
<ul>
<!-- Tutaj pojawią się elementy listy -->
</ul>
</article>
Co tu się dzieje? Tworzymy osobną sekcję (dla czytelności ujęłam ją w <article>
, podobnie jak inne elementy w aside) z nagłówkiem „lista zakupów:”. Pod nagłówkiem jest formularz <form>
zawierający pole tekstowe (<input type="text">
) oraz przycisk do dodania pozycji. Używamy formularza, bo to najprostszy sposób, by po kliknięciu przycisku lub wciśnięciu Enter uruchomić obsługę dodawania elementu – przeglądarka domyślnie spróbuje wysłać formularz, co później przechwycimy w JavaScript.
Polu input dodałam placeholder="np. 2 banany"
, żeby podpowiedzieć użytkownikowi, co może wpisać (to tekst, który wyświetla się w polu, dopóki nic nie wpiszesz). Atrybut button type="submit"
sprawia, że kliknięcie traktowane jest jak wysłanie formularza. Na koniec mamy pustą listę <ul>
– to właśnie tutaj JavaScript będzie dodawał kolejne elementy listy zakupów wpisane przez użytkownika. Na starcie lista jest pusta (wewnątrz <ul>
nic nie ma poza komentarzem pomocniczym), bo przecież użytkownik jeszcze nic nie dodał.
Uwaga: Jeśli teraz odświeżysz stronę i zobaczysz nasz formularz, możesz spróbować wpisać tekst w pole i nacisnąć Dodaj. Zauważysz, że… strona się przeładowała, a wpis zniknął. Bez obaw – to normalne! 🙂 Formularz bez obsługi JavaScript próbuje wysłać dane (których my nigdzie nie odbieramy), więc efekt jest taki, że przeładowuje stronę. W kolejnej części kursu zajmiemy się obsługą tego formularza za pomocą JS (m.in. zablokujemy to domyślne przeładowanie), tak aby po kliknięciu przycisku dodać element do listy. Na razie ważne jest tylko to, że HTML został przygotowany i jest połączony z plikiem JavaScript.
Ćwiczenia
Na koniec proponuję kilka prostych ćwiczeń, żeby lepiej zrozumieć dodane elementy i poeksperymentować samodzielnie:
- Zmień placeholder – Edytuj tekst placeholdera w polu input na inny. Np. zamiast „np. 2 banany” wpisz „Dodaj produkt…” albo cokolwiek innego przychodzi Ci do głowy. Zapisz i odśwież stronę, zobacz czy zmiana zadziałała.
- Zmień tekst przycisku – Podobnie, zmień napis na przycisku Dodaj na inny, np. Dodaj do listy albo nawet +. Dzięki temu zobaczysz, jak łatwo dostosować HTML do własnych potrzeb.
- Dodaj swój
console.log
– W plikuscript.js
dopisz dodatkową linię zconsole.log
, np.console.log('Hello from JS!')
albo po polskuconsole.log('Dzia\u0142am \u015bwietnie!')
. Odśwież stronę i sprawdź w konsoli, czy Twój komunikat również się pojawił. Możesz dodać ich więcej – to Twój plac zabaw.
Jeśli udało Ci się wykonać wszystkie powyższe kroki, to gratulacje! Masz już podstawowy szkielet prostej aplikacji webowej. W kolejnej części zaczniemy pisać kod JavaScript, który tchnie życie w naszą aplikącję lista zakupów – będziemy reagować na kliknięcia, dodawać elementy do listy, jednym słowem: dziać się będzie magia JS! Do zobaczenia nast\u0119pnym razem i powodzenia w eksperymentach.
Lista zakupów – efekty
Po zaimplementowaniu zmian widzimy pierwsze efekty w postaci pola do wpisywania elementów do listy oraz przycisk do ich dodawania. Na poniższym zrzucie ekranu widać również otwartą konsolę w narzędziach programistycznych z wartością z pliku script.js
.
Wszystkie zmiany dokonane w tym wpisie znajdziesz w repozytorium.

Bonus – lista zakupów a dostępność
Kiedyś napisałam już tekst o dostępności i nadal jest to dla mnie bardzo ważny obszar budowania stron i aplikacji. Dlatego też chciałabym pokazać Ci ten krótki kawałek kodu, ale wzbogacony o atrybuty, które poprawiają dostępność.
<article role="region" aria-labelledby="shopping-list-heading">
<h3 id="shopping-list-heading">lista zakupów:</h3>
<form>
<input
type="text"
placeholder="np. 2 banany"
aria-label="Wpisz produkt do listy zakupów"
aria-describedby="shopping-input-hint"
/>
<button type="submit" aria-label="Dodaj produkt do listy zakupów">Dodaj</button>
</form>
<ul
aria-live="polite"
aria-label="Twoja lista zakupów"
id="shopping-input-hint"
>
<!-- Tutaj pojawią się elementy listy -->
</ul>
</article>
Co się pojawiło i dlaczego?
role="region"
iaria-labelledby
w<article>
– umożliwia technologiom asystującym rozpoznanie tego bloku jako logicznej sekcji o nazwie „lista zakupów”.aria-label
winput
ibutton
– opisuje te elementy dla czytnika ekranowego (bo nie mają widocznegolabel
).aria-describedby
+id
wul
– pozwala połączyć pole z informacją pomocniczą (w tym przypadku uprościliśmy – info znajduje się przy liście).
Dla czytelności w tym „ćwiczebnym” projekcie nie będę dodawała tych atrybutów, wolę jednak skupić się na kodzie JavaScript. Pamiętaj jednak, że dostępność jest ważna!