INF.03-05-25.06-SGCzerwiec 2025 · 33 kroki · ok. 83 min · 41 kryteriów z klucza
Rozwiązanie krok po kroku: Salon fotograficzny online (Nowoczesny kod (grid))
To drugi sposób rozwiązania tego samego arkusza: salon fotograficzny z bazą fotografia, stroną zamowienie.html z galerią, formularzem zamówienia i koszykiem oraz podstronami regulamin.html i uslugi.html. Obie wersje spełniają wszystkie 41 kryteriów klucza - różni je sposób pisania kodu.
Czym ta wersja różni się od podstawowej:
blok główny na siatce CSS z nazwanymi obszarami: sekcja zamówienia po lewej, nawigacja i koszyk po prawej, szerokości 35% / 50% w grid-template-columns - bez float i clear w układzie,
galeria z display: flow-root - blok sam obejmuje pływające obrazy, nie trzeba clear w kolejnym bloku; kolory z arkusza w zmiennych CSS,
skrypt od pierwszej linijki z nasłuchiwaczem (addEventListener), podpięty w <head> z defer,
nazwa pliku z File API (files[0].name) zamiast cięcia ścieżki C:\fakepath\…, ceny w obiekcie zamiast drabinki if, sprawdzenie, czy wybrano plik i podano liczbę kopii,
każde zamówienie w koszyku to osobny blok <article>, a tekst ustawiany przez textContent i szablony tekstowe.
Kroki nadal idą zdanie po zdaniu za treścią arkusza, a podgląd rośnie z każdym krokiem i działa jak strona na egzaminie. Zdjęcia i baza pochodzą z prawdziwego archiwum pliki6; zrzuty to wyniki zapytań wykonanych na tej bazie w MariaDB.
Jak liczą się punkty. Klucz ma 41 kryteriów (R.1.1 - R.5.9), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 31 punktów. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.
Suwak i strzałki obok niego - albo ←→ na klawiaturze - przechodzą krok po kroku; wyjaśnienie, pliki i podgląd zmieniają się razem z krokiem.
Lista „Etap” przenosi od razu do wybranego etapu.
„Rozwiązuję samodzielnie” chowa rozwiązanie kroku - najpierw własna próba, potem odsłonięcie.
„Tryb prezentacji” pokazuje same kroki, bez menu strony - na rzutnik.
Etap 1: Baza danych
Kroki 1-5 · po tym etapie masz 6 z 41 kryteriów (pkt)
Krok 1: Baza fotografia, import i zrzut import.png
Kryteria:
R.1.1 Wykonany import bazy danych fotografia, czynność udokumentowana w pliku import.png
ok. 4 min
Polecenie z arkusza
Utwórz bazę danych o nazwie fotografia, z zestawem polskich znaków (np. utf8_unicode_ci). Z rozpakowanego archiwum zaimportuj tabele z pliku fotografia.sql. Wykonaj zrzut ekranu po imporcie. Zapisz zrzut w formacie PNG pod nazwą import. Nie kadruj zrzutu.
CREATE DATABASE fotografia CHARACTER SET utf8 COLLATE utf8_unicode_ci; (albo Nowa w phpMyAdmin).
Import → fotografia.sql. Plik sam zawiera CREATE DATABASE IF NOT EXISTS fotografia i USE fotografia - baza już istnieje, więc pierwsza linia nic nie zmienia, a druga kieruje import do właściwej bazy. Powstają zamowienia (81 wierszy) i zdjecia (2 rodzaje papieru z ceną). Kluczem relacji jest tekstowe pole rodzaj.
Zrzut całego ekranu z paskiem zadań jako import.png (w tym arkuszu wszystkie zrzuty w PNG).
Typowe błędy
Wartości rodzaj mają polskie znaki („błyszczący”) - przy złym zestawie znaków porównanie w zapytaniu 3 nie znajdzie żadnego wiersza.
Krok 2: Zapytanie 1: duże zamówienia na papierze matowym
Kryteria: ,
R.1.2 Zapisany plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Wykonane zapytanie 1 wybierające jedynie pola plik, nr_klienta, liczba_odbitek dla zamówień na papierze matowym, z liczbą odbitek większą od 100. W pliku z kwerendami lub na zrzucie istnieje zapis np. SELECT plik, nr_klienta, liczba_odbitek FROM zamowienia WHERE liczba_odbitek > 100 AND rodzaj = "matowy"; oraz wynik działania zapytania udokumentowany zrzutem, na którym widocznych jest dokładnie 6 wierszy z numerami klienta: 2, 6, 5, 8, 2, 3
ok. 3 min
Polecenie z arkusza
Zapytanie 1: wybierające jedynie pola plik, nr_klienta, liczba_odbitek dla zamówień na papierze matowym, z liczbą odbitek większą od 100.
Dwa warunki połączone AND, każdy w osobnej linii - czytelne i łatwe do zmiany. Napis 'matowy' w apostrofach (standard SQL), liczba bez. Wynik: 6 wierszy, klienci 2, 6, 5, 8, 2, 3. Zapytania w kwerendy.txt z komentarzem -- nad każdym; zrzut: kw1.png.
Typowe błędy
OR zamiast AND daje kilkadziesiąt wierszy zamiast sześciu.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT plik, nr_klienta, liczba_odbitekFROM zamowieniaWHERE rodzaj = 'matowy' AND liczba_odbitek > 100;
Podgląd strony po tym kroku
Krok 3: Zapytanie 2: wartość zamówień klienta 3
Kryteria:
R.1.4 Wykonane zapytanie 2 wybierające dla klienta o identyfikatorze 3 wartości jego zamówień obliczane na podstawie liczby odbitek i ceny, alias „Do zapłaty”. W pliku z kwerendami lub na zrzucie istnieje zapis np. SELECT (liczba_odbitek*cena) AS "Do zapłaty" FROM zamowienia JOIN zdjecia USING(rodzaj) WHERE nr_klienta = 3; (możliwe też porównanie kluczy po ON lub WHERE; dodatkowo AS opcjonalne, dozwolone dowolne kolumny po SELECT) oraz wynik działania zapytania udokumentowany zrzutem, na którym widocznych jest dokładnie 7 wierszy: 157, 157, 16.50, 157, 7, 15.40, 219.8
ok. 4 min
Polecenie z arkusza
Zapytanie 2: wybierające dla klienta o identyfikatorze 3 wartości jego zamówień, obliczane na podstawie liczby odbitek i ceny, nazwa kolumny (alias) „Do zapłaty”. Należy posłużyć się relacją.
FROM zamowienia AS z JOIN zdjecia AS f ON f.rodzaj = z.rodzaj - aliasy tabel i złączenie po polu rodzaj,
z.liczba_odbitek * f.cena - iloczyn kolumn z dwóch tabel,
AS `Do zapłaty` - alias ze spacją i polskimi literami. W MariaDB i MySQL nazwy (kolumn, aliasów) ujmuje się w odwrotne apostrofy; cudzysłów z klucza też zadziała, ale w tych bazach oznacza zwykle napis, a nie nazwę.
JOIN bez ON daje każdemu zamówieniu obie ceny - 14 wierszy zamiast 7.
kwerendy.txtTekstzmienione: 6 linii
-- Zapytanie 1SELECT plik, nr_klienta, liczba_odbitekFROM zamowieniaWHERE rodzaj = 'matowy' AND liczba_odbitek > 100;-- Zapytanie 2SELECT z.liczba_odbitek * f.cena AS `Do zapłaty`FROM zamowienia AS zJOIN zdjecia AS f ON f.rodzaj = z.rodzajWHERE z.nr_klienta = 3;
Podgląd strony po tym kroku
Krok 4: Zapytanie 3: suma odbitek na papierze błyszczącym
Kryteria:
R.1.5 Wykonane zapytanie 3 zliczające sumę wszystkich odbitek na papierze błyszczącym. W pliku z kwerendami lub na zrzucie istnieje zapis np. SELECT SUM(liczba_odbitek) FROM zamowienia WHERE rodzaj = "błyszczący"; oraz wynik działania zapytania udokumentowany zrzutem, na którym jest widoczna wartość 4291
ok. 2 min
Polecenie z arkusza
Zapytanie 3: zliczające sumę wszystkich odbitek na papierze błyszczącym.
SUM(liczba_odbitek) z aliasem odbitki_blyszczace - wynik ma nazwę zamiast SUM(liczba_odbitek). Wynik: 4291. Zrzut: kw3.png.
Typowe błędy
COUNT liczy wiersze (zamówienia), a nie sumę odbitek.
kwerendy.txtTekstzmienione: 5 linii
-- Zapytanie 1SELECT plik, nr_klienta, liczba_odbitekFROM zamowieniaWHERE rodzaj = 'matowy' AND liczba_odbitek > 100;-- Zapytanie 2SELECT z.liczba_odbitek * f.cena AS `Do zapłaty`FROM zamowienia AS zJOIN zdjecia AS f ON f.rodzaj = z.rodzajWHERE z.nr_klienta = 3;-- Zapytanie 3SELECT SUM(liczba_odbitek) AS odbitki_blyszczaceFROM zamowieniaWHERE rodzaj = 'błyszczący';
Podgląd strony po tym kroku
Krok 5: Zapytanie 4: konto użytkownika Anna
Kryteria:
R.1.6 Wykonane zapytanie 4 tworzące konto użytkownika Anna na localhost z hasłem @NNa. W pliku z kwerendami lub na zrzucie istnieje zapis np. CREATE USER 'Anna'@'localhost' IDENTIFIED BY '@NNa'; oraz wynik działania zapytania udokumentowany zrzutem, na którym jest widoczny komunikat o poprawnie wykonanym zapytaniu (dopuszczalny jest błąd informujący o niewybraniu bazy)
ok. 2 min
Polecenie z arkusza
Zapytanie 4: tworzące konto użytkownika Anna na localhost z hasłem @NNa.
CREATE USER 'Anna'@'localhost' IDENTIFIED BY '@NNa'; - konto, które może logować się tylko z tego komputera. Nowe konto nie ma jeszcze żadnych uprawnień; w prawdziwej pracy następnym krokiem byłoby GRANT tylko na potrzebne tabele (zasada najmniejszych uprawnień). Arkusz tego nie wymaga. Zrzut kw4.png: komunikat o wykonaniu.
Typowe błędy
Bez @'localhost' konto dostaje host % - może logować się z dowolnego komputera.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT plik, nr_klienta, liczba_odbitekFROM zamowieniaWHERE rodzaj = 'matowy' AND liczba_odbitek > 100;-- Zapytanie 2SELECT z.liczba_odbitek * f.cena AS `Do zapłaty`FROM zamowienia AS zJOIN zdjecia AS f ON f.rodzaj = z.rodzajWHERE z.nr_klienta = 3;-- Zapytanie 3SELECT SUM(liczba_odbitek) AS odbitki_blyszczaceFROM zamowieniaWHERE rodzaj = 'błyszczący';-- Zapytanie 4CREATE USER 'Anna'@'localhost' IDENTIFIED BY '@NNa';
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 6-16 · po tym etapie masz 20 z 41 kryteriów (pkt)
Krok 6: Przeskalowanie grafiki 10.jpg
Kryteria:
R.2.1 Grafika 10.jpg została przeskalowana z zachowaniem proporcji do wysokości 200 px, odpowiadająca temu szerokość to 267 px (±5 px)
ok. 3 min
Polecenie z arkusza
Cechy grafiki 10.jpg: grafikę należy przeskalować z zachowaniem proporcji do wysokości 200 px.
10.jpg ma 560 × 420 px; GIMP Obraz → Skaluj obraz, wysokość 200 px z zamkniętym łańcuchem - szerokość wyjdzie 267 px (klucz: ±5). Pozostałe zdjęcia już mają 267 × 200 px.
Podgląd strony po tym kroku
Krok 7: Podstrony regulamin.html i uslugi.html
ok. 1 min
Polecenie z arkusza
Składa się z podstron o nazwach zamowienie.html, regulamin.html, uslugi.html. W pliku regulamin.html należy zapisać jedynie: „Regulamin”. W pliku uslugi.html należy zapisać jedynie: „Usługi”.
Arkusz mówi „jedynie”, więc w każdym pliku tylko jedno słowo, bez szkieletu HTML. Przeglądarka i tak je wyświetli (sama rozpozna kodowanie UTF-8 przy „ł”). Nazwa pliku uslugi.html bez polskich liter - tak jak w odnośniku.
regulamin.htmlHTMLnowy plik
Regulamin
uslugi.htmlHTMLnowy plik
Usługi
Podgląd strony po tym kroku (regulamin.html)
Krok 8: Plik zamowienie.html: HTML5, język i kodowanie
Kryteria:
R.2.2 W pliku zamowienie.html zapisana deklaracja HTML5 <!DOCTYPE HTML>, deklaracja języka zawartości: polski np. <html lang="pl">, w sekcji head znajduje się jawnie podany standard kodowania polskich znaków
ok. 2 min
Polecenie z arkusza
Cechy strony zamowienie.html: zapisana w języku HTML5. Zadeklarowany polski język zawartości witryny. Jawnie zastosowany właściwy standard kodowania polskich znaków.
<!DOCTYPE html>, <html lang="pl">, <meta charset="UTF-8"> jako pierwszy element <head>.
R.3.2 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie style.css formatowanie CSS pochodzi jedynie z tego arkusza
ok. 1 min
Polecenie z arkusza
Tytuł strony widoczny na karcie przeglądarki: „Fotografia”. Arkusz stylów w pliku o nazwie style.css prawidłowo połączony z kodem strony.
<title>Fotografia</title> (R.2.3) i <link rel="stylesheet" href="style.css"> (R.3.2) - w tym arkuszu plik nazywa się style.css. Meta viewport dla telefonów.
R.2.4 W sekcji body zdefiniowany jest podział na bloki za pomocą semantycznych znaczników HTML 5: header, section (lub figure) , main-> section+nav+section, footer
ok. 2 min
Polecenie z arkusza
Podział strony na bloki zrealizowany za pomocą semantycznych znaczników bloków języka HTML5 tak, aby po uruchomieniu w przeglądarce układ bloków na stronie był zgodny z ilustracją 3. Zawartość bloku głównego: bloki sekcji lewej, nawigacyjny i sekcji prawej.
Układ z klucza R.2.4: <header>, <section> galerii, <main> z <section> + <nav> + <section>, <footer>. Identyfikatory mówią o treści: gallery, order (zamówienie), cart (koszyk) - nie o położeniu. Na wąskim ekranie koszyk mógłby trafić pod zamówienie i nazwa right byłaby myląca.
Typowe błędy
Nawigacja poza <main> nie spełnia R.2.4 - klucz wymaga jej między dwiema sekcjami bloku głównego.
R.2.6 Blok sekcji obrazów zawiera 10 obrazów od 1.jpg do 10.jpg. Wszystkie obrazy mają tekst alternatywny „obrazy do sprzedaży” oraz atrybut title, taki sam jak nazwa pliku, np. 1.jpg
ok. 3 min
Polecenie z arkusza
Zawartość bloku nagłówkowego: nagłówek pierwszego stopnia o treści „Fotografia artystyczna”. Zawartość bloku sekcji obrazów: 10 obrazów od 1.jpg do 10.jpg. Wszystkie obrazy mają tekst alternatywny „obrazy do sprzedaży” oraz tekst dymka podpowiedzi taki sam jak nazwa pliku, np. 1.jpg.
<h1> w nagłówku i dziesięć <img> z alt z arkusza i title równym nazwie pliku - title to dymek z ilustracji 2 (R.2.6). Galeria jest statyczna, jak każe arkusz: obrazy nie pochodzą z bazy.
Typowe błędy
Zamiana alt z title kosztuje R.2.6.
zamowienie.htmlHTMLzmienione: 11 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <metaname="viewport"content="width=device-width, initial-scale=1"> <title>Fotografia</title> <linkrel="stylesheet"href="style.css"></head><body> <header> <h1>Fotografia artystyczna</h1> </header> <sectionid="gallery"> <imgsrc="1.jpg"alt="obrazy do sprzedaży"title="1.jpg"> <imgsrc="2.jpg"alt="obrazy do sprzedaży"title="2.jpg"> <imgsrc="3.jpg"alt="obrazy do sprzedaży"title="3.jpg"> <imgsrc="4.jpg"alt="obrazy do sprzedaży"title="4.jpg"> <imgsrc="5.jpg"alt="obrazy do sprzedaży"title="5.jpg"> <imgsrc="6.jpg"alt="obrazy do sprzedaży"title="6.jpg"> <imgsrc="7.jpg"alt="obrazy do sprzedaży"title="7.jpg"> <imgsrc="8.jpg"alt="obrazy do sprzedaży"title="8.jpg"> <imgsrc="9.jpg"alt="obrazy do sprzedaży"title="9.jpg"> <imgsrc="10.jpg"alt="obrazy do sprzedaży"title="10.jpg"> </section> <main> <sectionid="order"> </section> <nav> </nav> <sectionid="cart"> </section> </main> <footer> </footer></body></html>
Podgląd strony po tym kroku (zamowienie.html)
Krok 12: Sekcja zamówienia: pole pliku i liczba kopii
Kryteria:
R.3.6 Pierwsze pole edycyjne jest typu file z atrybutem np. accept="image/jpeg" lub accept =".jpg, .jpeg", drugie pole edycyjne jest typu number
ok. 3 min
Polecenie z arkusza
Zawartość sekcji lewej: nagłówek trzeciego stopnia o treści „Zamówienie”. Etykieta „Wybierz obraz: ”, powiązana z polem edycyjnym znajdującym się obok. Pole edycyjne przeznaczone do wyboru pliku. Akceptuje tylko obrazy w formacie JPEG. Poniżej etykieta „Liczba Kopii: ”, powiązana z polem edycyjnym znajdującym się obok. Pole edycyjne przeznaczone do wpisywania jedynie liczb.
<h3> i dwie pary <label for> + pole: type="file" z accept="image/jpeg" (okno wyboru pokaże tylko JPEG-i) i type="number" (R.3.6). Pole liczby dostaje min="1" i step="1" - strzałki nie zejdą poniżej jednej kopii i nie podadzą ułamka. To podpowiedź dla przeglądarki; skrypt i tak sprawdzi liczbę.
Etykieta i pole stoją w jednej linii, a <br> kończy linię formularza - tu znacznik łamania jest na miejscu, bo arkusz każe ustawić kolejne kontrolki poniżej.
Typowe błędy
<label> bez for nie jest powiązana z polem - klucz R.2.7 wymaga powiązanych etykiet.
zamowienie.htmlHTMLzmienione: 5 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <metaname="viewport"content="width=device-width, initial-scale=1"> <title>Fotografia</title> <linkrel="stylesheet"href="style.css"></head><body> <header> <h1>Fotografia artystyczna</h1> </header> <sectionid="gallery"> <imgsrc="1.jpg"alt="obrazy do sprzedaży"title="1.jpg"> <imgsrc="2.jpg"alt="obrazy do sprzedaży"title="2.jpg"> <imgsrc="3.jpg"alt="obrazy do sprzedaży"title="3.jpg"> <imgsrc="4.jpg"alt="obrazy do sprzedaży"title="4.jpg"> <imgsrc="5.jpg"alt="obrazy do sprzedaży"title="5.jpg"> <imgsrc="6.jpg"alt="obrazy do sprzedaży"title="6.jpg"> <imgsrc="7.jpg"alt="obrazy do sprzedaży"title="7.jpg"> <imgsrc="8.jpg"alt="obrazy do sprzedaży"title="8.jpg"> <imgsrc="9.jpg"alt="obrazy do sprzedaży"title="9.jpg"> <imgsrc="10.jpg"alt="obrazy do sprzedaży"title="10.jpg"> </section> <main> <sectionid="order"> <h3>Zamówienie</h3> <labelfor="image">Wybierz obraz: </label> <inputtype="file"id="image"accept="image/jpeg"><br> <labelfor="copies">Liczba Kopii: </label> <inputtype="number"id="copies"min="1"step="1"><br> </section> <nav> </nav> <sectionid="cart"> </section> </main> <footer> </footer></body></html>
Podgląd strony po tym kroku (zamowienie.html)
Krok 13: Pola opcji papieru i przycisk
Kryteria: ,
R.2.7 W sekcji lewej umieszczone dwa pola edycyjne z powiązanymi etykietami, kolejno: "Wybierz obraz:" i "Liczba kopii:", dwa pola opcji: "Papier błyszczący" i "Papier matowy" oraz przycisk "Dodaj do koszyka"
R.3.5 Pierwsze pole opcji jest domyślnie zaznaczone. W jednym momencie można zaznaczyć tylko jedno pole opcji
ok. 3 min
Polecenie z arkusza
Poniżej pole opcji „Papier błyszczący”, domyślnie zaznaczone. Poniżej pole opcji „Papier matowy”. W jednym momencie można zaznaczyć tylko jedno pole opcji. Przycisk „Dodaj do koszyka”, którego kliknięcie wywołuje skrypt.
Dwa pola type="radio" ze wspólnym name="paper" - wspólna nazwa robi z nich grupę, w której zaznaczone jest zawsze jedno; checked przy błyszczącym (R.3.5). Każde pole ma value (glossy, matte) - skrypt odczyta wartość zaznaczonego pola zamiast sprawdzać po kolei, które jest zaznaczone.
Przycisk ma id, po którym znajdzie go skrypt, i nie ma onclick - obsługę kliknięcia dopisze skrypt. type="button" mówi wprost, że przycisk niczego nie wysyła.
Typowe błędy
Różne name w polach radio pozwalają zaznaczyć oba naraz - R.3.5 przepada.
zamowienie.htmlHTMLzmienione: 5 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <metaname="viewport"content="width=device-width, initial-scale=1"> <title>Fotografia</title> <linkrel="stylesheet"href="style.css"></head><body> <header> <h1>Fotografia artystyczna</h1> </header> <sectionid="gallery"> <imgsrc="1.jpg"alt="obrazy do sprzedaży"title="1.jpg"> <imgsrc="2.jpg"alt="obrazy do sprzedaży"title="2.jpg"> <imgsrc="3.jpg"alt="obrazy do sprzedaży"title="3.jpg"> <imgsrc="4.jpg"alt="obrazy do sprzedaży"title="4.jpg"> <imgsrc="5.jpg"alt="obrazy do sprzedaży"title="5.jpg"> <imgsrc="6.jpg"alt="obrazy do sprzedaży"title="6.jpg"> <imgsrc="7.jpg"alt="obrazy do sprzedaży"title="7.jpg"> <imgsrc="8.jpg"alt="obrazy do sprzedaży"title="8.jpg"> <imgsrc="9.jpg"alt="obrazy do sprzedaży"title="9.jpg"> <imgsrc="10.jpg"alt="obrazy do sprzedaży"title="10.jpg"> </section> <main> <sectionid="order"> <h3>Zamówienie</h3> <labelfor="image">Wybierz obraz: </label> <inputtype="file"id="image"accept="image/jpeg"><br> <labelfor="copies">Liczba Kopii: </label> <inputtype="number"id="copies"min="1"step="1"><br> <inputtype="radio"id="glossy"name="paper"value="glossy"checked> <labelfor="glossy">Papier błyszczący</label><br> <inputtype="radio"id="matte"name="paper"value="matte"> <labelfor="matte">Papier matowy</label><br> <buttontype="button"id="add-button">Dodaj do koszyka</button> </section> <nav> </nav> <sectionid="cart"> </section> </main> <footer> </footer></body></html>
Podgląd strony po tym kroku (zamowienie.html)
Krok 14: Blok nawigacyjny: lista odnośników
Kryteria: ,
R.2.8 W bloku nawigacyjnym umieszczona jedna lista punktowana z trzema elementami, zastosowane znaczniki <ul> i <li>
R.3.3 Wybranie odnośnika "Regulamin" otwiera stronę regulamin.html, "Usługi" otwiera uslugi.html , „Zdjęcia” inicjuje otwarcie strony "https://pixabay.com"
ok. 2 min
Polecenie z arkusza
Zawartość bloku nawigacyjnego: lista punktowana (nieuporządkowana) z elementami: odnośnik prowadzący do podstrony regulamin.html o treści „Regulamin”, odnośnik prowadzący do podstrony uslugi.html o treści „Usługi”, odnośnik prowadzący do strony internetowej https://pixabay.com o treści „Zdjęcia”.
<ul> z trzema <li> (R.2.8): dwa odnośniki względne do podstron i jeden pełny adres https://pixabay.com (R.3.3). Lista w <nav> to standardowy zapis menu - czytnik ekranu ogłasza „nawigacja, lista, 3 elementy”.
Typowe błędy
href="pixabay.com" bez https:// szuka pliku w folderze strony.
zamowienie.htmlHTMLzmienione: 5 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <metaname="viewport"content="width=device-width, initial-scale=1"> <title>Fotografia</title> <linkrel="stylesheet"href="style.css"></head><body> <header> <h1>Fotografia artystyczna</h1> </header> <sectionid="gallery"> <imgsrc="1.jpg"alt="obrazy do sprzedaży"title="1.jpg"> <imgsrc="2.jpg"alt="obrazy do sprzedaży"title="2.jpg"> <imgsrc="3.jpg"alt="obrazy do sprzedaży"title="3.jpg"> <imgsrc="4.jpg"alt="obrazy do sprzedaży"title="4.jpg"> <imgsrc="5.jpg"alt="obrazy do sprzedaży"title="5.jpg"> <imgsrc="6.jpg"alt="obrazy do sprzedaży"title="6.jpg"> <imgsrc="7.jpg"alt="obrazy do sprzedaży"title="7.jpg"> <imgsrc="8.jpg"alt="obrazy do sprzedaży"title="8.jpg"> <imgsrc="9.jpg"alt="obrazy do sprzedaży"title="9.jpg"> <imgsrc="10.jpg"alt="obrazy do sprzedaży"title="10.jpg"> </section> <main> <sectionid="order"> <h3>Zamówienie</h3> <labelfor="image">Wybierz obraz: </label> <inputtype="file"id="image"accept="image/jpeg"><br> <labelfor="copies">Liczba Kopii: </label> <inputtype="number"id="copies"min="1"step="1"><br> <inputtype="radio"id="glossy"name="paper"value="glossy"checked> <labelfor="glossy">Papier błyszczący</label><br> <inputtype="radio"id="matte"name="paper"value="matte"> <labelfor="matte">Papier matowy</label><br> <buttontype="button"id="add-button">Dodaj do koszyka</button> </section> <nav> <ul> <li><ahref="regulamin.html">Regulamin</a></li> <li><ahref="uslugi.html">Usługi</a></li> <li><ahref="https://pixabay.com">Zdjęcia</a></li> </ul> </nav> <sectionid="cart"> </section> </main> <footer> </footer></body></html>
Podgląd strony po tym kroku (zamowienie.html)
Krok 15: Sekcja koszyka i blok na zamówienia
Kryteria:
R.2.9 W sekcji prawej umieszczony element blokowy (np. <div> lub <section>)
ok. 2 min
Polecenie z arkusza
Zawartość sekcji prawej: nagłówek trzeciego stopnia o treści „Koszyk”. Blok, w którym zostanie umieszczony efekt działania skryptu.
<h3> i pusty <div id="cart-items"> (R.2.9) - do niego skrypt będzie dokładał zamówienia. Atrybut aria-live="polite" każe czytnikowi ekranu przeczytać to, co skrypt dopisze, gdy użytkownik skończy bieżącą czynność - bez niego niewidomy klient nie dowiedziałby się, że coś trafiło do koszyka.
zamowienie.htmlHTMLzmienione: 3 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <metaname="viewport"content="width=device-width, initial-scale=1"> <title>Fotografia</title> <linkrel="stylesheet"href="style.css"></head><body> <header> <h1>Fotografia artystyczna</h1> </header> <sectionid="gallery"> <imgsrc="1.jpg"alt="obrazy do sprzedaży"title="1.jpg"> <imgsrc="2.jpg"alt="obrazy do sprzedaży"title="2.jpg"> <imgsrc="3.jpg"alt="obrazy do sprzedaży"title="3.jpg"> <imgsrc="4.jpg"alt="obrazy do sprzedaży"title="4.jpg"> <imgsrc="5.jpg"alt="obrazy do sprzedaży"title="5.jpg"> <imgsrc="6.jpg"alt="obrazy do sprzedaży"title="6.jpg"> <imgsrc="7.jpg"alt="obrazy do sprzedaży"title="7.jpg"> <imgsrc="8.jpg"alt="obrazy do sprzedaży"title="8.jpg"> <imgsrc="9.jpg"alt="obrazy do sprzedaży"title="9.jpg"> <imgsrc="10.jpg"alt="obrazy do sprzedaży"title="10.jpg"> </section> <main> <sectionid="order"> <h3>Zamówienie</h3> <labelfor="image">Wybierz obraz: </label> <inputtype="file"id="image"accept="image/jpeg"><br> <labelfor="copies">Liczba Kopii: </label> <inputtype="number"id="copies"min="1"step="1"><br> <inputtype="radio"id="glossy"name="paper"value="glossy"checked> <labelfor="glossy">Papier błyszczący</label><br> <inputtype="radio"id="matte"name="paper"value="matte"> <labelfor="matte">Papier matowy</label><br> <buttontype="button"id="add-button">Dodaj do koszyka</button> </section> <nav> <ul> <li><ahref="regulamin.html">Regulamin</a></li> <li><ahref="uslugi.html">Usługi</a></li> <li><ahref="https://pixabay.com">Zdjęcia</a></li> </ul> </nav> <sectionid="cart"> <h3>Koszyk</h3> <divid="cart-items"aria-live="polite"> </div> </section> </main> <footer> </footer></body></html>
Podgląd strony po tym kroku (zamowienie.html)
Krok 16: Stopka z numerem zdającego
Kryteria: ,
R.2.5 W bloku nagłówkowym umieszczony <h1> "Fotografia artystyczna", w sekcji lewej <h3> "Zamówienie", w prawej <h3> "Koszyk", w stopce paragraf z numerem zdającego
R.2.10 W stopce zastosowany dla numeru zdającego znacznik <em>
ok. 1 min
Polecenie z arkusza
Zawartość stopki: paragraf o treści „Autor strony: ”, dalej wstawiony numer zdającego. Numer zdającego jest zapisany za pomocą znacznika semantycznego oznaczającego tekst uwypuklony, formatowany domyślnie jako pochylony.
<em> - znacznik semantyczny uwypuklenia, domyślnie pochylony (R.2.10); <i> pochyla bez znaczenia. Tu stoi nazwisko autora rozwiązania - na egzaminie wpisujesz swój numer zdającego (PESEL). Z nagłówkami <h1>, dwoma <h3> i tym paragrafem to komplet R.2.5.
zamowienie.htmlHTMLzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <metaname="viewport"content="width=device-width, initial-scale=1"> <title>Fotografia</title> <linkrel="stylesheet"href="style.css"></head><body> <header> <h1>Fotografia artystyczna</h1> </header> <sectionid="gallery"> <imgsrc="1.jpg"alt="obrazy do sprzedaży"title="1.jpg"> <imgsrc="2.jpg"alt="obrazy do sprzedaży"title="2.jpg"> <imgsrc="3.jpg"alt="obrazy do sprzedaży"title="3.jpg"> <imgsrc="4.jpg"alt="obrazy do sprzedaży"title="4.jpg"> <imgsrc="5.jpg"alt="obrazy do sprzedaży"title="5.jpg"> <imgsrc="6.jpg"alt="obrazy do sprzedaży"title="6.jpg"> <imgsrc="7.jpg"alt="obrazy do sprzedaży"title="7.jpg"> <imgsrc="8.jpg"alt="obrazy do sprzedaży"title="8.jpg"> <imgsrc="9.jpg"alt="obrazy do sprzedaży"title="9.jpg"> <imgsrc="10.jpg"alt="obrazy do sprzedaży"title="10.jpg"> </section> <main> <sectionid="order"> <h3>Zamówienie</h3> <labelfor="image">Wybierz obraz: </label> <inputtype="file"id="image"accept="image/jpeg"><br> <labelfor="copies">Liczba Kopii: </label> <inputtype="number"id="copies"min="1"step="1"><br> <inputtype="radio"id="glossy"name="paper"value="glossy"checked> <labelfor="glossy">Papier błyszczący</label><br> <inputtype="radio"id="matte"name="paper"value="matte"> <labelfor="matte">Papier matowy</label><br> <buttontype="button"id="add-button">Dodaj do koszyka</button> </section> <nav> <ul> <li><ahref="regulamin.html">Regulamin</a></li> <li><ahref="uslugi.html">Usługi</a></li> <li><ahref="https://pixabay.com">Zdjęcia</a></li> </ul> </nav> <sectionid="cart"> <h3>Koszyk</h3> <divid="cart-items"aria-live="polite"> </div> </section> </main> <footer> <p>Autor strony: <em>Bartosz Bryniarski</em></p> </footer></body></html>
Podgląd strony po tym kroku (zamowienie.html)
Etap 3: Styl CSS
Kroki 17-23 · po tym etapie masz 31 z 41 kryteriów (pkt)
Krok 17: Zmienne z kolorami, krój i tło strony
Kryteria:
R.4.1 Ustawiony styl domyślny dla wszystkich selektorów (*): krój czcionki "Century Gothic", Arial (tylko taka kolejność)
ok. 2 min
Polecenie z arkusza
Domyślnie, dla wszystkich selektorów: krój czcionki Century Gothic, w przypadku braku Arial. Dla ciała strony: kolor tła BlanchedAlmond.
Kolory arkusza w zmiennych :root - Sienna występuje w nagłówku, stopce i odnośnikach, więc wpisana raz. * z krojem "Century Gothic", Arial - nazwa ze spacją w cudzysłowie, kolejność dokładnie z klucza (R.4.1: „tylko taka kolejność”, więc tu nie ma dopisanej rodziny sans-serif). Tło body ze zmiennej.
Krok 19: Sekcja zamówienia i siatka bloku głównego
Kryteria:
R.4.8 Ustawiony dla sekcji lewej styl box-shadow: 5px 5px 10px DimGray;
ok. 4 min
Polecenie z arkusza
Dla sekcji lewej: kolor tła NavajoWhite, marginesy zewnętrzne 10 px, wewnętrzne 20 px, szerokość 35%, wysokość 400 px, cień o przesunięciu 5 px w obu osiach, rozmyciu 10 px i kolorze DimGray.
Szerokość 35% wynika z siatki, więc ten krok ją zakłada:
display: grid na <main> i grid-template-columns: 35% 50% - kolumna zamówienia i kolumna nawigacji z koszykiem (klucz R.4.4 dopuszcza szerokości w grid-template-columns),
grid-template-areas - mapa: zamówienie zajmuje oba wiersze lewej kolumny, w prawej jest nawigacja, a pod nią koszyk - dokładnie ilustracja 3,
column-gap: 2% - odstęp między kolumnami bez marginesów, align-items: start - bloki nie rozciągają się na wysokość wiersza, tylko mają swoje wysokości z arkusza.
Sekcja zamówienia: grid-area: order, tło ze zmiennej, margin: 10px, padding: 20px, wysokość 400 px i cień bloku box-shadow: 5px 5px 10px (R.4.8) - przesunięcie, przesunięcie, rozmycie, kolor.
W siatce margines (10 px) i dopełnienie (20 px) mieszczą się w kolumnie 35%, więc sama sekcja wychodzi trochę węższa niż w wersji podstawowej (przy oknie 1280 px ok. 415 px zamiast 475 px). Kolumna ma dokładnie 35%, tak jak wymaga arkusz.
Typowe błędy
text-shadow daje cień literom, a nie blokowi - R.4.8 wymaga box-shadow.
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z ilustracją 3 w arkuszu egzaminacyjnym (prawidłowo zastosowane właściwości CSS decydujące o układzie bloków na stronie, np. float i clear albo display flex albo grid albo position)
R.4.7 Ustawione dla bloku nagłówkowego i stopki rozmiar czcionki 130%, oraz dla sekcji prawej overflow: auto;
ok. 2 min
Polecenie z arkusza
Dla bloku nawigacyjnego: szerokość 50%, wysokość 50 px. Dla sekcji prawej: szerokość 50%, wysokość 420 px, paski przewijania pojawiające się tylko w przypadku przepełnienia bloku.
Każdy blok dostaje swój obszar mapy (grid-area), a szerokość 50% daje kolumna siatki. Wysokości z arkusza; overflow: auto przy koszyku - pasek pojawi się dopiero, gdy zamówień przybędzie ponad 420 px.
Teraz układ zgadza się z ilustracją 3 (R.3.1): zamówienie po lewej, po prawej nawigacja i pod nią koszyk - bez float i bez clear w stopce. Szerokości 35% / 50% w siatce i wysokości 400 / 50 / 420 px są kompletne; ostatnia część R.4.4 to szerokość obrazów.
Dla pola edycyjnego i przycisku: jedynie zewnętrzny margines górny 20 px. Dla selektora elementu listy: sposób wyświetlania liniowo-blokowy.
margin-top: 20px tylko z góry dla input i button - kontrolki rozsuwają się w pionie. Elementy listy li (selektorem znacznika, jak każe arkusz) z display: inline-block stają w jednym rzędzie, a punktory znikają, bo element przestaje być elementem listy w sensie wyświetlania. Tu arkusz narzuca konkretną wartość, więc nie ma display: flex na liście - choć do menu w rzędzie nadawałby się równie dobrze.
Typowe błędy
margin: 20px ze wszystkich stron odsuwa pola także od etykiet - arkusz mówi „jedynie górny”.
Krok 22: Obrazy: szerokość, opływanie i galeria bez clear
Kryteria:
R.4.9 Ustawiony dla selektora li: display: inline-block; oraz dla obrazu: float: left
ok. 3 min
Polecenie z arkusza
Dla selektora obrazu: szerokość 10%, opływanie po prawej stronie (obraz po lewej stronie).
img { width: 10%; float: left; } - arkusz każe opływanie, czyli float, a klucz R.4.9 sprawdza float: left. Tu float jest narzucony i zostaje: robi dokładnie to, do czego go wymyślono - tekst opływa obraz (w koszyku podpisy staną obok miniatury). Dziesięć obrazów po 10% zajmuje jeden rząd galerii (R.4.4: 10% dla img).
Problem pływających obrazów: blok, w którym tylko one są, ma zerową wysokość i następne bloki wjeżdżają pod obrazy. Stary sposób to clear: both w kolejnym bloku albo „clearfix”. Nowy - display: flow-root na galerii: blok tworzy własny kontekst formatowania i obejmuje pływające dzieci. Galeria ma wysokość obrazów, a blok główny zaczyna się pod nią.
Typowe błędy
float: right stawia obraz po prawej - arkusz w nawiasie wyjaśnia: obraz po lewej.
R.4.2 Ustawiony kolor tła dla ciała strony BlanchedAlmond, dla bloku nagłówkowego i stopki Sienna, dla sekcji lewej NavajoWhite
R.4.3 Ustawiony biały kolor czcionki dla bloków nagłówkowego i stopki, oraz Sienna dla selektora a
R.4.4 Ustawiona szerokość dla sekcji lewej 35%, dla bloków nawigacyjnego i sekcji prawej 50% (width lub grid-template-columns lub flex) , dla selektora img 10%. Ustawione wysokości sekcji lewej 400px, bloku nawigacyjnego 50px, sekcji prawej 420px
R.4.6 Ustawione marginesy wewnętrzne (padding ) dla bloku nagłówkowego i stopki 5px, dla sekcji lewej 20px oraz marginesy zewnętrzne (margin) dla sekcji lewej 10px , margin-top: 20px dla pola edycyjnego i przycisku, margin-right: 30px dla odnośnika (ustawione min. 6 właściwości)
R.4.10 Gdy kursor znajdzie się na odnośniku jego kolor czcionki zamienia się na #4C1900
ok. 2 min
Polecenie z arkusza
Dla selektora odnośnika: kolor czcionki Sienna, jedynie zewnętrzny margines prawy 30 px. W momencie, gdy kursor znajdzie się na odnośniku jego kolor czcionki zamienia się na #4C1900.
a selektorem znacznika: kolor ze zmiennej i margin-right: 30px - z marginesami nagłówka, stopki, sekcji zamówienia i pól to komplet R.4.6. a:hover z ciemnym brązem (R.4.10). Teraz komplet także R.4.2 (tła strony, nagłówka, stopki i sekcji zamówienia), R.4.3 (biały tekst nagłówka i stopki, Sienna odnośników) i R.4.4 (szerokości i wysokości).
Kroki 24-31 · po tym etapie masz 41 z 41 kryteriów (pkt)
Krok 24: Plik script.js z defer i cennik w obiekcie
Kryteria:
R.5.1 Skrypt napisany w języku JavaScript i zawiera on przynajmniej jedną poprawną składniowo instrukcję wynikającą z treści zadania
ok. 3 min
Polecenie z arkusza
Wykonywany po stronie klienta, po kliknięciu przycisku. Oblicza cenę na podstawie liczby kopii i rodzaju papieru. Dla papieru błyszczącego cena jednostkowa wynosi 1,5 zł, dla papieru matowego - 2 zł.
<script src="script.js" defer> w <head>: defer uruchamia skrypt dopiero po wczytaniu całego HTML, więc przycisk i koszyk już istnieją.
Pierwsza rzecz w skrypcie to cennik - obiekt, w którym kluczem jest wartość pola radio (glossy, matte), a wartością cena za odbitkę. Stała ma nazwę wielkimi literami (PRICES), bo to dana konfiguracyjna, która się nie zmienia. Zamiast drabinki if (glossy) ... else ... cena będzie odczytywana jednym PRICES[paper], a trzeci rodzaj papieru to jedna nowa linia w obiekcie.
script.jsJavaScriptnowy plik
const PRICES = { glossy: 1.5, matte: 2,};
zamowienie.htmlHTMLzmienione: 1 linia
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <metaname="viewport"content="width=device-width, initial-scale=1"> <title>Fotografia</title> <linkrel="stylesheet"href="style.css"> <scriptsrc="script.js"defer></script></head><body> <header> <h1>Fotografia artystyczna</h1> </header> <sectionid="gallery"> <imgsrc="1.jpg"alt="obrazy do sprzedaży"title="1.jpg"> <imgsrc="2.jpg"alt="obrazy do sprzedaży"title="2.jpg"> <imgsrc="3.jpg"alt="obrazy do sprzedaży"title="3.jpg"> <imgsrc="4.jpg"alt="obrazy do sprzedaży"title="4.jpg"> <imgsrc="5.jpg"alt="obrazy do sprzedaży"title="5.jpg"> <imgsrc="6.jpg"alt="obrazy do sprzedaży"title="6.jpg"> <imgsrc="7.jpg"alt="obrazy do sprzedaży"title="7.jpg"> <imgsrc="8.jpg"alt="obrazy do sprzedaży"title="8.jpg"> <imgsrc="9.jpg"alt="obrazy do sprzedaży"title="9.jpg"> <imgsrc="10.jpg"alt="obrazy do sprzedaży"title="10.jpg"> </section> <main> <sectionid="order"> <h3>Zamówienie</h3> <labelfor="image">Wybierz obraz: </label> <inputtype="file"id="image"accept="image/jpeg"><br> <labelfor="copies">Liczba Kopii: </label> <inputtype="number"id="copies"min="1"step="1"><br> <inputtype="radio"id="glossy"name="paper"value="glossy"checked> <labelfor="glossy">Papier błyszczący</label><br> <inputtype="radio"id="matte"name="paper"value="matte"> <labelfor="matte">Papier matowy</label><br> <buttontype="button"id="add-button">Dodaj do koszyka</button> </section> <nav> <ul> <li><ahref="regulamin.html">Regulamin</a></li> <li><ahref="uslugi.html">Usługi</a></li> <li><ahref="https://pixabay.com">Zdjęcia</a></li> </ul> </nav> <sectionid="cart"> <h3>Koszyk</h3> <divid="cart-items"aria-live="polite"> </div> </section> </main> <footer> <p>Autor strony: <em>Bartosz Bryniarski</em></p> </footer></body></html>
Podgląd strony po tym kroku (zamowienie.html)
Krok 25: Funkcja addToCart i nasłuchiwacz przycisku
Kryteria: ,
R.3.4 Zdefiniowane dla przycisku zdarzenie związane z jego wciśnięciem, które uruchamia funkcję skryptu (obsługa zdarzenia zdefiniowana w HTML np. onClick lub w skrypcie np.addEventListener zmienna.onClick = …)
R.5.9 W skryptach zastosowana przynajmniej jedna zmienna lub funkcja oraz nazwy wszystkich funkcji i zmiennych są w języku polskim lub angielskim i odzwierciedlają cel zastosowania
ok. 3 min
Polecenie z arkusza
Przycisk „Dodaj do koszyka”, którego kliknięcie wywołuje skrypt.
Pola i blok koszyka są wyszukiwane raz, przy starcie skryptu, i trzymane w stałych - funkcja nie musi szukać ich przy każdym kliknięciu. Funkcja addToCart() jest na razie pusta.
Ostatnia linia rejestruje nasłuchiwacz: addEventListener('click', addToCart) - funkcja przekazana bez nawiasów (nie wywołana). Klucz R.3.4 wymienia tę drogę wprost obok onclick. HTML zostaje czystą strukturą, a całe zachowanie strony jest w jednym pliku.
Typowe błędy
addEventListener('click', addToCart()) z nawiasami wywołuje funkcję raz, przy wczytaniu strony - kliknięcie potem nic nie robi.
R.5.2 Skrypt pobiera dane z przynajmniej jednej kontrolki, np. zastosowana funkcja document.getElementById z parametrem, który zdefiniowany w kontrolce jako id
ok. 3 min
Polecenie z arkusza
Pobiera dane z kontrolek.
Number(copiesInput.value) - value pola jest zawsze napisem, Number zamienia go na liczbę od razu przy odczycie (pusty napis daje 0),
document.querySelector('input[name="paper"]:checked') - selektor CSS z tabeli 1 arkusza: pole radio z grupy paper, które jest zaznaczone. Jego value to glossy albo matte. Jedna linia zamiast sprawdzania pól po kolei.
Pole liczby kopii jest odczytywane przez getElementById - tak, jak podaje przykład w kluczu R.5.2.
R.5.3 Skrypt oblicza cenę na podstawie liczby kopii pobranej z kontrolki i rodzaju papieru: błyszczący 1.5 zł, matowy 2 zł
ok. 2 min
Polecenie z arkusza
Oblicza cenę na podstawie liczby kopii i rodzaju papieru. Dla papieru błyszczącego cena jednostkowa wynosi 1,5 zł, dla papieru matowego - 2 zł.
copies * PRICES[paper] - nawias kwadratowy odczytuje z obiektu wartość pod kluczem zapisanym w zmiennej: dla paper równego 'glossy' to 1,5, dla 'matte' - 2 (R.5.3). Cena jest stałą const, bo nie zmienia się po obliczeniu.
Typowe błędy
PRICES.paper (z kropką) szuka klucza o nazwie dosłownie „paper” i daje undefined - przy kluczu w zmiennej zawsze nawias kwadratowy.
Ustala nazwę pliku z wartości pobranej z pierwszego pola edycyjnego.
Pole type="file" ma File API (wspomina o nim ramka „File Input Type” w arkuszu): fileInput.files to lista wybranych plików, a files[0] - pierwszy z nich. Nazwa pliku to file.name - bez wycinania jej ze ścieżki C:\fakepath\7.jpg, którą przeglądarka podstawia w value.
Zanim cokolwiek trafi do koszyka, warunek sprawdza dane: brak pliku (!file), liczba kopii, która nie jest całkowita, albo mniejsza niż 1 - funkcja kończy się return. Bez tego puste kliknięcie dodawało do koszyka pusty obrazek i „Cena: 0”.
Klucz R.5.4 podaje lastIndexOf + substr jako przykład („np.”) - ocenia, czy skrypt ustala nazwę pliku. substr jest zresztą w JavaScript oznaczone jako przestarzałe.
R.5.5 Skrypt tworzy element img z ustaloną nazwą pliku i dodaje go do bloku w sekcji prawej
ok. 3 min
Polecenie z arkusza
Tworzy elementy i dodaje je do bloku z sekcji prawej (ilustracja 4): element DOM dla obrazu z ustaloną nazwą pliku.
Każde zamówienie dostaje własny blok <article> - samodzielną całość z obrazem i dwoma paragrafami. createElement('img') tworzy obraz, image.src = file.name wskazuje plik z folderu strony (zdjęcia leżą obok zamowienie.html), a alt z nazwą pliku opisuje miniaturę dla czytnika ekranu. Obraz trafia do bloku zamówienia, a blok - na koniec koszyka przez append (R.5.5).
Wypróbuj w podglądzie: wybierz dowolne z dziesięciu zdjęć galerii, wpisz liczbę kopii i kliknij przycisk.
Typowe błędy
image.src = fileInput.value podaje ścieżkę z fakepath, z której przeglądarka nie wczyta pliku.
Krok 30: Zamówienie w koszyku: liczba kopii i cena
Kryteria: , ,
R.5.6 Skrypt tworzy 2 elementy p z treścią i dodaje je do bloku w sekcji prawej
R.5.7 Skrypt wyświetla napisy: „Liczba kopii: <kopie>”, gdzie pole <> jest pobrane z kontrolki, „Cena: <cena>”, gdzie pole <> jest wyliczoną ceną
R.5.8 Po ponownym wypełnieniu kontrolek i kliknięciu przycisku poprzednie zamówienie nie znika, następne jest dodawane pod nim
ok. 3 min
Polecenie z arkusza
Element DOM dla paragrafu z treścią Liczba kopii: <kopie>, gdzie pole <> jest pobrane z kontrolki. Element DOM dla paragrafu z treścią Cena: <cena>, gdzie pole <> jest wyliczoną ceną.
Dwa paragrafy z treścią z szablonów tekstowych: w odwrotnych apostrofach ${copies} wstawia wartość zmiennej - czytelniej niż sklejanie plusem. Treść ustawia textContent, który zawsze wstawia zwykły tekst (R.5.6, R.5.7). item.append(image, copiesParagraph, priceParagraph) wkłada do bloku zamówienia wszystkie trzy elementy naraz, w tej kolejności.
Podgląd działa jak na ilustracji 4: trzy zamówienia - np. 10 kopii na matowym (Cena: 20), 7 na matowym (14) i 20 na błyszczącym (30) - stają jedno pod drugim, bo append dokłada na koniec i niczego nie kasuje (R.5.8).
Tworzy elementy i dodaje je do bloku z sekcji prawej (ilustracja 4).
Miniatura ma float: left, więc podpisy stoją obok niej, jak na ilustracji 4. Gdy jednak podpisy są niższe niż obraz, następna miniatura „wskoczyłaby” obok poprzedniej. Reguła #cart-items article { display: flow-root; } robi z każdego zamówienia blok, który obejmuje swój pływający obraz - kolejne zamówienie zawsze zaczyna się pod poprzednim. To ten sam mechanizm co w galerii, tym razem dla elementów tworzonych przez skrypt.
Krok 32 · po tym etapie masz 41 z 41 kryteriów (pkt)
Krok 32: Co jest inaczej i którą wersję wybrać
ok. 3 min
Polecenie z arkusza
Ocenie będzie podlegać 5 rezultatów: operacje na bazie danych, zawartość witryny internetowej, działanie witryny internetowej, styl CSS witryny internetowej, skrypt.
wersja podstawowa
ta wersja
blok główny
float: left na trzech blokach, clear: both w stopce
grid-template-areas
galeria z pływającymi obrazami
domyka ją clear w następnym bloku
display: flow-root
przycisk
onclick="addToCart()"
addEventListener w skrypcie
rodzaj papieru i cena
checked + if/else
:checked + obiekt PRICES
nazwa pliku
lastIndexOf + substr ze ścieżki
files[0].name
zamówienie w koszyku
trzy elementy wprost w bloku
blok <article> na zamówienie
float dla obrazów i inline-block dla elementów listy zostają w obu wersjach, bo arkusz nazywa te sposoby wyświetlania wprost.
Na egzaminie: wersja podstawowa idzie za podpowiedziami z tabeli 1 i z klucza (onclick, lastIndexOf, substr), więc łatwiej ją napisać bez dokumentacji. Ta wersja jest krótsza w skrypcie i odporna na puste pola - wybierz ją, jeśli querySelector z :checked i File API pisze się z pamięci.
Krok 33 · po tym etapie masz 41 z 41 kryteriów (pkt)
Krok 33: Plik przeglądarka.txt i nagranie płyty
ok. 5 min
Polecenie z arkusza
Po zakończeniu pracy utwórz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowana była poprawność działania witryny. Nagraj płytę z rezultatami pracy.
Na płycie: zdjęcia 1.jpg - 10.jpg, import.png, kw1.png - kw4.png, kwerendy.txt, przeglądarka.txt, regulamin.html, uslugi.html, zamowienie.html, style.css i script.js. Po nagraniu sprawdź odczyt płyty.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
To jedno z możliwych rozwiązań. Egzaminator ocenia spełnienie kryteriów z klucza odpowiedzi, a nie zgodność z tym kodem - inna, poprawna droga też daje punkty.
Autor rozwiązania: Bartosz Bryniarski. Licencja CC BY-NC 4.0 - kopiowanie i przeróbki do celów niekomercyjnych, z podaniem autora i źródła (link do tej strony) (zasady wykorzystania). Treść arkusza i klucza oceniania pochodzi z CKE.