INF.03-04-26.06-SGCzerwiec 2026 · 54 kroki · ok. 100 min · 39 kryteriów z klucza
Rozwiązanie krok po kroku: Strona rezerwacji biura podróży (Nowoczesny kod (grid, fieldset))
To drugi sposób rozwiązania tego samego arkusza. Wynik jest ten sam - baza wyprawy z czterema zapytaniami, grafika z przezroczystym tłem, strona rezerwacja.html z dwoma przyciskami przełączającymi sekcje i przewijaniem zdjęć - i tak samo spełnia każde kryterium klucza. Inna jest droga:
siatka CSS z nazwanymi obszarami w bloku głównym zamiast float i clear - szerokości 90%, 45% i 10% stoją w grid-template-columns, co klucz wprost dopuszcza, a blok boczny może stać w kodzie na końcu,
stan przycisków w atrybucie aria-pressed: skrypt tylko przełącza stan, a kolor DodgerBlue wynika z reguły CSS - całe formatowanie zostaje w styl.css,
grupy pól <fieldset disabled>: jedna właściwość wyłącza wszystkie kontrolki sekcji naraz,
skrypt w osobnym plikuskrypt.js z atrybutem defer: tablica obiektów z danymi wycieczek napędza i przewijanie, i dziewięć zdjęć w bloku bocznym, obsługa przez addEventListener, zawinięcie resztą z dzielenia, tekst przez textContent.
Na końcu krótkie porównanie z wersją podstawową (zakładka obok). Baza i grafiki pochodzą z prawdziwego archiwum pliki4, zapytania zostały wykonane na tej bazie w MariaDB, a skrypt sprawdzony w prawdziwej przeglądarce: kolory przycisków, aktywność kontrolek i kolejność zdjęć zgadzają się z ilustracjami 4 i 5 oraz z kolejnością podaną w arkuszu.
Jak liczą się punkty. Klucz ma 39 kryteriów (R.1.1 - R.5.7), każde za 1 punkt. Próg zdania to 75%, czyli 30 punktów. Przy każdym kroku jest napisane, które kryteria spełnia.
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-7 · po tym etapie masz 6 z 39 kryteriów (pkt)
Krok 1: Baza danych wyprawy
ok. 2 min
Polecenie z arkusza
Utwórz bazę danych o nazwie wyprawy, z zestawem polskich znaków (np. utf8_polish_ci)
Archiwum pliki4.7z z pulpitu rozpakuj hasłem RezErw@cjE i załóż folder z numerem zdającego. W phpMyAdmin Nowa → nazwa wyprawy, porównywanie utf8_polish_ci. To samo w SQL:
CREATE DATABASE wyprawy CHARACTER SET utf8 COLLATE utf8_polish_ci;
Krok 2: Import tabel z pliku wyprawy.sql
ok. 2 min
Polecenie z arkusza
Do utworzonej bazy zaimportuj tabele z pliku wyprawy.sql
Baza wyprawy → Import → wyprawy.sql → Wykonaj. Dwie tabele z ilustracji 1: wycieczki (3 miejsca) i rezerwacje (10 wierszy) z kluczem obcym Wycieczki_id.
Krok 3: Zrzut ekranu import.png
Kryteria:
R.1.1 Wykonany import tabel do bazy danych wyprawy - plik import.png
ok. 2 min
Polecenie z arkusza
Wykonaj zrzut ekranu po imporcie. Zapisz zrzut w formacie PNG pod nazwą import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel
Cały ekran z paskiem zadań, zapis jako import.png. Wszystkie zrzuty w tym arkuszu są w PNG.
Typowe błędy
Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany.
Krok 4: Zapytanie 1: rezerwacje z all inclusive
Kryteria: ,
R.1.2 W pliku kwerendy.txt zapisane co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Wykonane zapytanie 1 wybierające jedynie imiona i nazwiska osób rezerwujących wycieczki z wyżywieniem typu 3. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko FROM rezerwacje WHERE wyzywienie = 3; oraz na zrzucie są dokładnie 4 rekordy dla: Anny, Jana, Judyty i Jolanty
ok. 2 min
Polecenie z arkusza
Zapytanie 1: wybierające jedynie imiona i nazwiska osób rezerwujących wycieczki z wyżywieniem typu 3 (all inclusive)
Każda klauzula w osobnej linii - przy dłuższych zapytaniach od razu widać, co jest listą kolumn, co źródłem, a co warunkiem. Wynik: Anna, Jan, Judyta i Jolanta, jak w kluczu. Zapytanie do kwerendy.txt, zrzut kw1.png.
Krok 5: Zapytanie 2: liczba rezerwacji do Rzymu z Warszawy
Kryteria:
R.1.4 Wykonane zapytanie 2 zliczające rezerwacje na wycieczkę o id równym 2 i wylocie z Warszawy. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT COUNT(*) FROM rezerwacje WHERE Wycieczki_id = 2 AND wylot = "Warszawa"; oraz na zrzucie jest widoczna wartość 2
ok. 2 min
Polecenie z arkusza
Zapytanie 2: zliczające rezerwacje na wycieczkę o id równym 2 i wylocie z Warszawy
COUNT(*) liczy wiersze spełniające oba warunki połączone AND. Alias liczba_rezerwacji nadaje kolumnie wyniku czytelną nazwę zamiast COUNT(*) - arkusz go nie wymaga, ale zrzut od razu mówi, co oznacza liczba. Napis w apostrofach - to standard SQL (cudzysłowy też zadziałają w MySQL, ale nie w każdej bazie). Wynik: 2, zrzut kw2.png.
Krok 6: Zapytanie 3: miejsca wycieczek z rezerwującymi
Kryteria:
R.1.5 Wykonane zapytanie 3 wybierające jedynie miejsca wycieczek i odpowiadające im imiona i nazwiska rezerwujących. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT miejsce, imie, nazwisko FROM wycieczki JOIN rezerwacje ON wycieczki.id = Wycieczki_id; (lub porównanie kluczy po WHERE ) oraz na zrzucie jest dokładnie 10 rekordów
ok. 3 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie miejsca wycieczek i odpowiadające im imiona i nazwiska rezerwujących. Należy posłużyć się relacją
FROM wycieczki AS w i JOIN rezerwacje AS r - krótkie aliasy tabel,
ON r.Wycieczki_id = w.id - klucz obcy rezerwacji równa się kluczowi głównemu wycieczki,
w.miejsce, r.imie - przedrostek mówi, z której tabeli jest kolumna; przy dwóch tabelach z kolumną id bez przedrostków łatwo o niejednoznaczność.
Warunek złączenia w ON (a nie w WHERE z przecinkiem między tabelami) oddziela „jak połączyć tabele” od „które wiersze wybrać”. Wynik: 10 wierszy, zrzut kw3.png.
kwerendy.txtTekstzmienione: 5 linii
-- Zapytanie 1SELECT imie, nazwiskoFROM rezerwacjeWHERE wyzywienie = 3;-- Zapytanie 2SELECT COUNT(*) AS liczba_rezerwacjiFROM rezerwacjeWHERE Wycieczki_id = 2 AND wylot = 'Warszawa';-- Zapytanie 3SELECT w.miejsce, r.imie, r.nazwiskoFROM wycieczki AS wJOIN rezerwacje AS r ON r.Wycieczki_id = w.id;
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: liczba osób na każdej wycieczce
Kryteria:
R.1.6 Wykonane zapytanie 4 wybierające jedynie miejsca wycieczek i sumujące liczbę osób, dla których została zarezerwowana wycieczka. Jedna osoba (jeden rekord) może rezerwować wycieczkę dla kilku osób. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT miejsce, SUM(osob) FROM wycieczki JOIN rezerwacje ON wycieczki.id = Wycieczki_id GROUP BY miejsce; (lub porównanie kluczy po WHERE ) oraz na zrzucie są dane: Barcelona 5, Londyn 4, Rzym 10
ok. 3 min
Polecenie z arkusza
Zapytanie 4: wybierające jedynie miejsca wycieczek i sumujące liczbę osób, dla których została zarezerwowana wycieczka. Jedna osoba (jeden rekord) może rezerwować wycieczkę dla kilku osób. Należy posłużyć się relacją i grupowaniem
To samo złączenie, GROUP BY w.miejsce zlewa wiersze jednego miejsca w jeden, a SUM(r.osob) dodaje liczby osób z rezerwacji grupy (alias liczba_osob). Wynik: Barcelona 5, Londyn 4, Rzym 10 - jak w kluczu. Zrzut kw4.png.
Typowe błędy
COUNT(*) zamiast SUM(r.osob) liczy rezerwacje, a nie osoby - arkusz uprzedza, że jedna rezerwacja może być dla kilku osób.
kwerendy.txtTekstzmienione: 6 linii
-- Zapytanie 1SELECT imie, nazwiskoFROM rezerwacjeWHERE wyzywienie = 3;-- Zapytanie 2SELECT COUNT(*) AS liczba_rezerwacjiFROM rezerwacjeWHERE Wycieczki_id = 2 AND wylot = 'Warszawa';-- Zapytanie 3SELECT w.miejsce, r.imie, r.nazwiskoFROM wycieczki AS wJOIN rezerwacje AS r ON r.Wycieczki_id = w.id;-- Zapytanie 4SELECT w.miejsce, SUM(r.osob) AS liczba_osobFROM wycieczki AS wJOIN rezerwacje AS r ON r.Wycieczki_id = w.idGROUP BY w.miejsce;
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-35 · po tym etapie masz 20 z 39 kryteriów (pkt)
Krok 8: Grafika osoba.png: przezroczyste tło
ok. 3 min
Polecenie z arkusza
Tło przezroczyste
W GIMP-ie Warstwa → Przezroczystość → Dodaj kanał alfa, Zaznaczenie rozmyte (próg ok. 15) i klik w jasnoszare tło, Edycja → Wyczyść. Tło usuwa się na pełnej rozdzielczości - granica sylwetki wychodzi dokładniej niż na obrazie 100 px.
Podgląd strony po tym kroku
Krok 9: Grafika osoba.png: szerokość 100 px
Kryteria:
R.2.1 Grafika osoba.png ma wymiary 100 px na 100 px i tło przezroczyste
ok. 2 min
Polecenie z arkusza
Cechy grafiki osoba.png: Przeskalowana z zachowaniem proporcji do szerokości 100 px
Obraz → Skaluj obraz, szerokość 100 px przy zamkniętym łańcuchu - obraz jest kwadratowy, więc wychodzi 100 × 100 px. Eksport do PNG zachowuje kanał alfa.
Podgląd strony po tym kroku
Krok 10: Plik rezerwacja.html w HTML5
ok. 1 min
Polecenie z arkusza
Cechy strony rezerwacja: Zapisana w języku HTML5
Arkusz dopuszcza PHP albo HTML - bez kodu po stronie serwera wystarczy rezerwacja.html. <!DOCTYPE html> włącza tryb standardów HTML5.
R.2.3 W sekcji head znajduje się jawnie podany standard kodowania polskich znaków i tytuł strony "Biuro turystyczne"
ok. 1 min
Polecenie z arkusza
Tytuł strony widoczny na karcie przeglądarki: „Biuro turystyczne”
<title> w <head>. Obok <meta name="viewport"> - bez niego telefon pokazałby stronę pomniejszoną jak na monitorze. Arkusz tego nie wymaga, a w każdym współczesnym szablonie ta linia jest.
R.3.2 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.css formatowanie CSS pochodzi jedynie z tego arkusza
ok. 1 min
Polecenie z arkusza
Arkusz stylów w pliku o nazwie styl.css prawidłowo połączony z kodem strony
<link rel="stylesheet" href="styl.css">. W tej wersji w HTML nie ma ani jednego atrybutu style, a skrypt nie ustawia kolorów - całe formatowanie siedzi w styl.css.
Typowe błędy
Zła nazwa w href to brak stylów, a wtedy rezultat R.4 przepada.
Witryna składa się z podstron o nazwach rezerwacja (format PHP lub HTML), wycieczki.html. W pliku wycieczki.html należy zapisać „Strona w trakcie budowy”
Szkielet HTML5 z jednym akapitem. Odnośnik „Do strony głównej” będzie miał dokąd prowadzić.
wycieczki.htmlHTMLnowy plik
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Wycieczki</title></head><body> <p>Strona w trakcie budowy</p></body></html>
Podgląd strony po tym kroku (wycieczki.html)
Krok 16: Bloki semantyczne w kolejności treści
Kryteria:
R.2.4 W sekcji body zdefiniowany jest podział na bloki za pomocą semantycznych znaczników HTML5: header, main -> nav + section + section + aside, footer (dopuszcza się stosowanie bloków pomocniczych)
ok. 3 min
Polecenie z arkusza
Podział strony na bloki: nagłówkowy, główny i stopki. Blok główny zawiera bloki: nawigacyjny, dwa bloki sekcji i blok boczny. Podział zrealizowany za pomocą semantycznych znaczników języka HTML5 tak, aby po uruchomieniu w przeglądarce układ bloków był zgodny z ilustracją 3
header, w main kolejno nav, dwie section i aside, na końcu footer - dokładnie lista z klucza R.2.4. Blok boczny stoi w kodzie na końcu bloku głównego, bo to treść poboczna: czytnik ekranu przeczyta najpierw nawigację i formularz. Przy float musiałby stać pierwszy, żeby zaczynał się od góry; siatka CSS ustawia bloki niezależnie od kolejności w kodzie. Sekcje dostają identyfikatory client i trip - po nich siatka przypisze im miejsca.
Zawartość bloku bocznego: 9 obrazów z tekstem alternatywnym „wycieczki”. Obrazy są zapętlone: 1.jpg, 2.jpg, 3.jpg, 1.jpg itd. Sposób realizacji dowolny
„Sposób realizacji dowolny”, więc zdjęcia tworzy skrypt z danych. W pliku skrypt.js stoi tablica obiektów trips: każda wycieczka to para zdjęcie - miejsce. Ta sama tablica posłuży później przewijaniu w drugiej sekcji, więc zdjęcia i nazwy są zapisane w jednym miejscu.
Pętla for tworzy dziewięć obrazów (document.createElement('img')), plik bierze z indeksu i % trips.length - reszta z dzielenia przez 3 daje 0, 1, 2, 0, 1, 2... - i dokleja je do bloku bocznego metodą append. const dla wartości, których się nie przypisuje ponownie, let dla licznika pętli.
Skrypt jest podpięty w <head> atrybutem defer: przeglądarka pobiera go równolegle, ale wykonuje dopiero po wczytaniu całego HTML-u - querySelector('aside') znajdzie blok, choć znacznik <script> stoi wyżej. Klucz uznaje obrazy dodane skryptem (R.2.7: „w HTML lub skrypcie”).
Typowe błędy
<script src="skrypt.js"> w <head> bez defer wykona się przed powstaniem <aside> - querySelector zwróci null i skrypt przerwie się błędem.
Zawartość bloku nawigacyjnego: Przycisk o treści „Uczestnik”, którego kliknięcie powoduje wywołanie funkcji uczestnika
type="button" mówi wprost, że przycisk nie wysyła formularza. Atrybut aria-pressed="true" opisuje stan przycisku przełączającego: ten jest „wciśnięty”, bo na starcie aktywna jest sekcja klienta. Czytnik ekranu odczyta go jako „przycisk przełączający, wciśnięty”, a CSS pokoloruje przycisk właśnie po tym atrybucie. Obsługę kliknięcia dopisze skrypt.
Poniżej etykieta „Imię” oraz pole edycyjne z nią powiązane
Kontrolki sekcji trafiają do <fieldset> - znacznika grupującego pola formularza. Jego atrybut disabled wyłącza naraz wszystkie kontrolki w środku, więc skrypt przełączy całą sekcję jedną właściwością.
Para etykieta - pole stoi w akapicie <p>: akapit jest blokiem, więc para zaczyna się w nowej linii pod obrazem bez <br>. <label for="firstName"> wiąże etykietę z polem po id - kliknięcie w napis „Imię” ustawia kursor w polu. name przyda się, gdy formularz kiedyś zacznie wysyłać dane.
R.2.7 W bloku sekcji pierwszej znajduje się obraz osoba.png z tekstem alternatywnym "Klient" w bloku sekcji drugiej - 1.jpg z tekstem alternatywnym "Wycieczka" w bloku bocznym znajduje się 9 obrazów (w HTML lub skrypcie, część z nich może być ukryta)
ok. 1 min
Polecenie z arkusza
Obraz 1.jpg z tekstem alternatywnym „wycieczka”
Identyfikator tripImage - skrypt podmieni src. Z tym krokiem są wszystkie obrazy z klucza: osoba.png, 1.jpg i dziewięć zdjęć z pętli w bloku bocznym.
Krok 31: Pole liczby osób: 1 - 4, wartość 2, nieaktywne
ok. 2 min
Polecenie z arkusza
Etykieta „Liczba osób:” oraz pole edycyjne z nią powiązane. Pole jest typu numerycznego, przyjmuje wartości od 1 do 4, wyświetla wartość 2. Pole jest nieaktywne
type="number" z min="1", max="4" i value="2". Pole stoi w drugiej grupie, <fieldset id="bookingFields" disabled> - wyłączona grupa wyłącza wszystkie kontrolki w środku, więc samo pole nie potrzebuje własnego disabled. Działa to dokładnie tak samo: pole jest wyszarzone i nie da się go zmienić (selektor :disabled je obejmuje), a kolejne kontrolki tej sekcji trafią do tej samej grupy.
Typowe błędy
Egzaminator sprawdza działanie: pole ma być nieaktywne na stronie (R.3.5). Spróbuj w nie kliknąć w przeglądarce - jeśli da się zmienić wartość, grupa nie ma disabled.
Poniżej etykieta „Miejsce wylotu:” oraz pole listy rozwijanej z nią powiązane. Opcje listy: „Warszawa”, „Kraków”, „Wrocław”. Pole listy jest nieaktywne
<select> z trzema opcjami w tej samej wyłączonej grupie - jest nieaktywny bez własnego atrybutu.
R.3.6 Pole z liczbą osób jest typu number, przyjmuje wartości od 1 do 4, wyświetla wartość 2 (value lub placeholder) W danym momencie może być wybrane tylko jedno pole opcji, domyślnie pierwsze pole opcji jest zaznaczone
ok. 2 min
Polecenie z arkusza
Poniżej zgrupowane trzy pola opcji (w jednym momencie możliwe jest wybranie tylko jednego pola), powiązane z etykietami „Śniadania”, „Śniadania i obiadokolacje”, „All inclusive”. Wszystkie pola są nieaktywne, pierwsze jest zaznaczone
Wspólne name="food" łączy pola opcji w grupę - zaznaczenie jednego odznacza pozostałe. value to numer wyżywienia, taki sam jak w polu wyzywienie tabeli rezerwacje (1, 2, 3) - gdy formularz zacznie wysyłać dane, wartość pasuje od razu do bazy. Pierwsze pole ma checked. Wszystkie są nieaktywne, bo stoją w wyłączonej grupie.
Typowe błędy
Różne name przy polach opcji pozwalają zaznaczyć wszystkie trzy - klucz wymaga, by można było wybrać tylko jedno (R.3.6).
R.2.8 W bloku sekcji pierwszej znajdują się dwa pola edycyjne W bloku sekcji drugiej - pole edycyjne, lista rozwijana, trzy pola opcji i przycisk. Co najmniej jedno pole ma powiązaną etykietę (label z for i id lub zagnieżdżenie kontrolki w label)
ok. 1 min
Polecenie z arkusza
Poniżej przycisk „Sprawdź cenę”. Przycisk nie ma funkcjonalności
Przycisk stoi za grupą pól: arkusz nie każe go wyłączać, a w wyłączonym fieldset też stałby się nieaktywny. type="button" - nic nie wysyła.
R.2.5 W bloku nagłówkowym znajduje się <h1>: "Rezerwacja wycieczek" w blokach sekcji <h2>: "Dane Klienta" i "Dane rezerwacji" oraz <h4>: "Barcelona", w stopce <p> z numerem zdającego
R.2.10 Numer zdającego jest w znaczniku <em>
ok. 1 min
Polecenie z arkusza
Zawartość bloku stopki: paragraf o treści „Autor strony: ”, dalej wstawiony numer zdającego. Numer zdającego jest zapisany w semantycznym znaczniku oznaczającym tekst uwypuklony, formatowany domyślnie jako pochylony
Tekst uwypuklony to <em>. Na egzaminie wpisujesz w nim swój numer zdającego (PESEL) - tutaj stoi imię i nazwisko autora rozwiązania.
Kroki 36-45 · po tym etapie masz 31 z 39 kryteriów (pkt)
Krok 36: Zmienne z kolorami i krój czcionki
Kryteria:
R.4.1 domyślne formatowanie selektorów (*): krój czcionki "Bookman Old Style"
ok. 2 min
Polecenie z arkusza
Domyślnie, dla wszystkich selektorów: krój czcionki „Bookman Old Style”
Na początku zmienne CSS (custom properties) w :root: kolor SkyBlue występuje w arkuszu trzy razy, a zaokrąglenie 15 px dwa razy - zmiana w jednym miejscu zmieni wszystkie. Odwołanie to var(--sky). Potem selektor * z krojem; nazwa ze spacjami w cudzysłowie.
styl.cssCSSnowy plik
:root {--sky: SkyBlue;--dodger: DodgerBlue;--radius: 15px;}* {font-family: "Bookman Old Style";}
Krok 39: Siatka bloku głównego zgodna z ilustracją 3
Kryteria: ,
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; żaden blok nie zachodzi na inne bloki - sprawdzić w inspektorze)
R.4.5 wyrównanie tekstu: blok nagłówkowy, nawigacyjny, stopka - do środka
ok. 4 min
Polecenie z arkusza
Dla bloku nawigacyjnego: szerokość 90%, wyrównanie tekstu do środka
Blok główny dostaje display: grid z trzema kolumnami 45% 45% 10% - to szerokości z arkusza: sekcja, sekcja, blok boczny. grid-template-areas rysuje układ z ilustracji 3 słowami: w pierwszym wierszu nawigacja zajmuje dwie kolumny (45% + 45% = 90%), w drugim stoją obie sekcje, a blok boczny zajmuje trzecią kolumnę w obu wierszach. Każdy blok dostaje swój obszar przez grid-area.
Klucz R.4.3 dopuszcza szerokości w grid-template-columns, a R.3.1 - układ na grid. Bloki nie mają ustawianych szerokości, więc nic nie może się nie zmieścić, a stopka stoi pod blokiem głównym bez clear. text-align: center w nawigacji wyśrodkowuje przyciski.
Typowe błędy
Nazwy w grid-template-areas muszą tworzyć prostokąty - obszar aside w obu wierszach w tej samej kolumnie jest poprawny, ale „rozjechany” (np. nav w dwóch nieprzylegających miejscach) unieważnia całą właściwość i bloki wracają jeden pod drugi.
Krok 41: Blok boczny: wysokość i ukryta zawartość wystająca
Kryteria: ,
R.4.4 wysokość: oba bloki sekcji - 640px, blok boczny - 700px
R.4.10 w przypadku przepełnienia (overflow) bloku bocznego zawartość wystająca poza blok jest ukryta
ok. 2 min
Polecenie z arkusza
Dla bloku bocznego: szerokość 10%, wysokość 700 px, w przypadku przepełnienia bloku zawartość wystająca poza blok jest ukryta
Szerokość 10% to trzecia kolumna siatki. Dopisane do istniejącej reguły aside: wysokość i overflow: hidden - dziewięć zdjęć jest wyższych niż 700 px, nadmiar zostaje obcięty bez paska przewijania.
R.4.2 kolor tła: ciało strony - AliceBlue, blok nagłówkowy, stopki, przycisków - SkyBlue
R.4.3 szerokość: blok nawigacyjny - 90%, oba bloki sekcji - 45%, blok boczny - 10% (width lub grid-template- columns lub flex ), obraz jedynie w bloku bocznym - 100%, przyciski 45%
R.4.6 marginesy wewnętrzne (padding ): blok nagłówkowy, stopka - 1px, przyciski - górny i dolny - 15px, pozostałe - 40px
Dla przycisku: kolor tła SkyBlue, szerokość 45%, zaokrąglenie rogów 15 px, marginesy wewnętrzne górny i dolny 15 px, pozostałe 40 px, marginesy zewnętrzne górny i dolny 3 px, pozostałe 2%
Skróty z dwiema wartościami (góra i dół, potem boki): padding: 15px 40px, margin: 3px 2%. Druga reguła to selektor atrybutubutton[aria-pressed="true"]: wciśnięty przycisk ma tło DodgerBlue. Dzięki temu „Uczestnik” jest ciemnoniebieski od pierwszego wczytania (stan początkowy z arkusza), a skrypt będzie tylko przełączał aria-pressed - kolor zawsze wynika ze stanu i nie da się ich rozkleić.
R.4.7 marginesy zewnętrzne (margin) : kontrolki na stronie - 3px, przyciski - górny i dolny - 3px, pozostałe - 2%
ok. 1 min
Polecenie z arkusza
Dla kontrolek (pola edycyjne, lista rozwijana, pola opcji): marginesy zewnętrzne 3 px
Pola i pola opcji to <input>, lista to <select>. Druga reguła zdejmuje ramkę i odstępy, które przeglądarka domyślnie rysuje wokół fieldset - grupy mają działać, a nie być widoczne.
Kroki 46-52 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 46: Stan początkowy i funkcja przełączająca: kolory przycisków
Kryteria: , ,
R.5.1 Skrypt w języku JavaScript zawiera przynajmniej jedną poprawną składniowo instrukcję wynikającą z treści zadania
R.5.2 Zastosowana przynajmniej jedna zmienna lub funkcja oraz nazewnictwo jest w języku polskim lub angielskim i odzwierciedla cel zastosowania
R.5.3 Odwołania do istniejących elementów DOM (np. document.getElementById) są zapisane zgodnie ze składnią
ok. 4 min
Polecenie z arkusza
Funkcja uczestnika wywoływana po wciśnięciu przycisku „Uczestnik” (ilustracja 4): Zmieniane są kolory tła przycisków: „Uczestnik” na DodgerBlue, „Rezerwacja” na SkyBlue
Stan początkowy z arkusza („Uczestnik” na DodgerBlue) jest już spełniony: aria-pressed="true" w HTML i reguła w CSS.
Funkcje uczestnika i rezerwacji różnią się tylko tym, która strona jest aktywna, więc w skrypcie jest jedna funkcja showPanel(isParticipant) z parametrem logicznym. Na górze cztery stałe z elementami strony (document.querySelector z selektorem CSS) - wyszukane raz, używane przy każdym kliknięciu. setAttribute('aria-pressed', isParticipant) zapisuje "true" przy przycisku aktywnym i "false" przy drugim (! odwraca wartość); kolor dobiera CSS.
R.3.3 Dla przynajmniej jednego przycisku zdefiniowane jest zdarzenie kliknięcia, które uruchamia funkcję skryptu
ok. 2 min
Polecenie z arkusza
Przycisk o treści „Uczestnik”, którego kliknięcie powoduje wywołanie funkcji uczestnika
addEventListener('click', ...) przypina obsługę kliknięcia w skrypcie - HTML zostaje bez atrybutów onclick. Funkcja strzałkowa () => showPanel(true) jest „funkcją uczestnika”: wywołuje wspólną funkcję z parametrem true. Samo showPanel(true) (bez strzałki) wywołałoby funkcję od razu przy wczytaniu.
Krok 50: Przycisk „Rezerwacja”: ta sama funkcja z false
Kryteria: ,
R.5.4 Po kliknięciu w przycisk jego kolor tła jest ustawiany na DodgerBlue, drugiego przycisku na SkyBlue (sprawdzić dla obu przycisków )
R.5.5 Po kliknięciu w każdy przycisk, kontrolki odpowiedniej sekcji są aktywne, w sąsiedniej sekcji są nieaktywne
ok. 2 min
Polecenie z arkusza
Funkcja rezerwacji wywoływana po wciśnięciu przycisku „Rezerwacja” (ilustracja 5): Zmieniane są kolory tła przycisków: „Uczestnik” na SkyBlue, „Rezerwacja” na DodgerBlue. Kontrolki pierwszego bloku sekcji są nieaktywne. Kontrolki drugiego bloku sekcji są aktywowane
Funkcja rezerwacji to () => showPanel(false): przy false każda z czterech linii daje ustawienie odwrotne - „Rezerwacja” wciśnięta, pola klienta wyłączone, pola rezerwacji włączone. Kliknij „Rezerwacja” w podglądzie: stan z ilustracji 5; „Uczestnik” przywraca stan z ilustracji 4. (W arkuszu stoi „na SkyBlue na” - drugie „na” to literówka.)
R.5.6 Po kliknięciu w znak przewijania w lewo obraz zmienia się na poprzedni, z zawinięciem: Barcelona -> Londyn - > Rzym -> Barcelona
ok. 4 min
Polecenie z arkusza
Funkcja wywoływana po wciśnięciu znaku «: Zmienia się obraz oraz nazwa miejsca wycieczki na poprzedni, w przypadku pierwszego – na ostatni (obrazy są przewijane do tyłu). Kolejność: 1.jpg „Barcelona”, 3.jpg „Londyn”, 2.jpg „Rzym”, 1.jpg „Barcelona, ...
Funkcja showTrip(step) przesuwa numer wycieczki o -1 albo 1. Zawinięcie robi reszta z dzielenia: dodane trips.length sprawia, że krok w tył z zera daje (0 - 1 + 3) % 3 = 2, czyli ostatnią wycieczkę, a nie liczbę ujemną. Zdjęcie i nazwę bierze z tej samej tablicy trips, która zbudowała blok boczny - pary zdjęcie - miejsce nie da się pomylić.
Nazwę wpisuje textContent, nie innerHTML: to zwykły tekst, więc przeglądarka nie czyta go jako HTML. Kliknij « w podglądzie: Londyn, Rzym, Barcelona.
Krok 52: Przewijanie do przodu i obsługa klawiatury
Kryteria:
R.5.7 Po kliknięciu w znak przewijania w prawo obraz zmienia się na następny, z zawinięciem: Barcelona -> Rzym - > Londyn -> Barcelona
ok. 3 min
Polecenie z arkusza
Funkcja wywoływana po wciśnięciu znaku »: Zmienia się obraz oraz nazwa miejsca wycieczki na następny, w przypadku ostatniego – na pierwszy. Kolejność: 1.jpg „Barcelona”, 2.jpg „Rzym”, 3.jpg „Londyn”, 1.jpg „Barcelona”, ...
Ta sama funkcja z krokiem 1: Rzym, Londyn, Barcelona. Do tego klawiatura: znaki z role="button" obiecują zachowanie przycisku, a prawdziwy przycisk reaguje na Enter i spację. Pętla for...of po obu znakach dopina zdarzenie keydown, które wywołuje ich kliknięcie (arrow.click()); preventDefault() blokuje przewinięcie strony spacją. Klucz tego nie sprawdza - to dopełnienie atrybutów z kroku ze znakiem «.
Krok 53 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 53: Co jest inaczej i którą wersję wybrać na egzaminie
ok. 2 min
Obie wersje dają komplet 39 punktów. Różnice:
wersja podstawowa
wersja nowoczesna
układ
float + clear, blok boczny pierwszy w kodzie
siatka z grid-template-areas, blok boczny na końcu
szerokości bloków
width każdego bloku
grid-template-columns: 45% 45% 10%
kolor przycisku
style.backgroundColor ze skryptu
aria-pressed + selektor atrybutu w CSS
wyłączanie pól
7 kontrolek osobno w każdej funkcji
fieldset.disabled - jedna linia na sekcję
skrypt
<script> w HTML, onclick, dwie funkcje
skrypt.js z defer, addEventListener, jedna funkcja z parametrem
przewijanie
dwie tablice, if przy granicy
tablica obiektów, reszta z dzielenia
zdjęcia bloku bocznego
9 znaczników <img>
pętla po tej samej tablicy
Na egzaminie wersja podstawowa jest bezpieczniejsza, gdy brakuje czasu: każdy wymóg arkusza widać w kodzie dosłownie (disabled przy każdym polu, kolor w skrypcie), więc łatwo go sprawdzić wzrokiem. Wersja nowoczesna jest krótsza i trudniej w niej o niespójność - kolor i stan przycisku nie mogą się rozjechać, a nowe pole formularza nie wymaga zmian w skrypcie. Tu warto sprawdzić w przeglądarce, że pola drugiej sekcji naprawdę są wyszarzone, bo atrybutu disabled przy nich nie widać.
Krok 54 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 54: 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. Umieść go w folderze z numerem zdającego. Nagraj płytę z rezultatami pracy.
W folderze z numerem zdającego: 1.jpg, 2.jpg, 3.jpg, import.png, kw1.png … kw4.png, kwerendy.txt, osoba.png, przeglądarka.txt, rezerwacja.html, skrypt.js, styl.css, wycieczki.html. Bez skrypt.js nie działają przyciski ani przewijanie. Płytę sprawdź po nagraniu.
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.