Przejdź do głównej treści
EE.09-02-23.01-SGStyczeń 2023 · 48 kroków · ok. 83 min · 38 kryteriów z klucza

Rozwiązanie krok po kroku: Galeria obrazów z przyciskami nawigacji (Wersja podstawowa)

Galeria zdjęć gór: baza gory z tabelą szczyty (26 najwyższych szczytów pasm górskich w Polsce), w której zapytania wybierają szczyty powyżej 1500 m i najwyższy szczyt, tworzą konto leon i nadają mu prawa do danych (CREATE USER, GRANT). Do tego zdjęcie wykadrowane w pionie (zamek i fragment gór), strona galeria.html z dużym zdjęciem, przyciskami „prev” i „next” oraz pięcioma miniaturami, style w styl2.css (cienie bloków, zaokrąglone miniatury z ramką pod kursorem) i skrypt JavaScript, który przełącza duże zdjęcie przyciskami i kliknięciem w miniaturę.

To arkusz EE.09 ze stycznia 2023 - kwalifikacji formuły 2017, którą zastąpiła INF.03. Kroki idą zdanie po zdaniu za treścią arkusza - przy każdym jest polecenie z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Skrypt jest napisany najprościej, polami i metodami z tabeli 1 arkusza (getElementById, zmiana atrybutu src, atrybut onclick), a na końcu jest krótki etap o zabezpieczeniach: odnośnik do obcej strony i konto w bazie danych.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, nasłuchiwacze)” jest drugi sposób rozwiązania tego samego arkusza: siatka CSS, zmienne z kolorami, skrypt w osobnym pliku z nasłuchiwaczami addEventListener i miniatury opisane atrybutami data- - obie wersje są zgodne z kluczem.

Baza i zdjęcia pochodzą z oryginalnego archiwum CKE zad2.zip (załącznik do pobrania na stronie arkusza, hasło w treści zadania). Zapytania i zrzuty są policzone na MariaDB 10.4 - tej samej, która jest w XAMPP; prawa konta leon sprawdzone logowaniem. Skrypt był uruchomiony w przeglądarce Chrome: kliknięcia przycisków i miniatur sprawdzone testem, układ bloków zmierzony.

Jak liczą się punkty. Klucz ma 38 kryteriów (R.1.1 - R.5.6), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 29 punktów - można stracić 9 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.

  1. Etap 1: Baza danych

    Kroki 1-8 · po tym etapie masz 7 z 38 kryteriów (pkt)

    Krok 1: Folder zdającego i archiwum zad2.zip

    ok. 2 min
    Polecenie z arkusza

    Na pulpicie konta Egzamin należy utworzyć folder. Jako nazwy folderu należy użyć numeru zdającego, którym został podpisany arkusz. Rozpakowane pliki należy umieścić w tym folderze. Zaleca się, aby rozpakowane pliki znajdowały się w tym samym folderze, co pliki strony. Po skończonej pracy wszystkie wyniki należy zapisać w tym folderze.

    Na pulpicie tworzysz folder nazwany numerem PESEL - w tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora, Bartosz Bryniarski. Archiwum zad2.zip rozpakowujesz do tego folderu, podając hasło !<MojaG@leri@>! - razem z wykrzyknikami i nawiasami ostrymi na obu końcach, a w środku dwa razy znak @ zamiast „a”. W archiwum jest szczyty.sql (tabela do importu), zdjecie.jpg (zdjęcie do wykadrowania) i pięć zdjęć galerii 1.jpg - 5.jpg.

    Zdjęcia zostają w tym samym folderze co strona - wtedy w kodzie wystarczy sama nazwa pliku, np. src="1.jpg", bez ścieżki.

    Typowe błędy

    Pliki zapisane poza folderem zdającego nie trafią na płytę - a ocenia się tylko to, co jest na płycie.

  2. Krok 2: XAMPP i baza gory

    ok. 2 min
    Polecenie z arkusza

    Za pomocą narzędzia phpMyAdmin wykonaj operacje na bazie danych: Utwórz bazę danych o nazwie gory

    W XAMPP Control Panel klikasz Start przy Apache i MySQL, potem w przeglądarce otwierasz http://localhost/phpmyadmin. Nowa w lewym panelu, nazwa gory (bez „ó”), porównywanie np. utf8_polish_ci, Utwórz. Porównywanie z rodziny utf8 zapisze „Śnieżka” i „Babia Góra” bez krzaków, a polish ustawi przy sortowaniu „Ś” po „S”.

    Typowe błędy

    Nazwa bazy musi brzmieć dokładnie gory - zapytanie 4 nadaje prawa do gory.*, a klucz R.1.1 sprawdza import właśnie do tej bazy. Komentarz w pliku szczyty.sql wspomina bazę gory2 - to tylko ślad po autorze arkusza, plik nie tworzy żadnej bazy.

  3. Krok 3: Import tabeli z pliku szczyty.sql i zrzut import.jpg

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych gory , czynność udokumentowano plikiem o nazwie import w formacie JPEG

    ok. 3 min
    Polecenie z arkusza

    Do bazy gory zaimportuj tabele z pliku szczyty.sql z rozpakowanego archiwum. Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w formacie JPEG i nazwij 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

    Zaznacz bazę gory w lewym panelu, karta Import, Wybierz plik → szczyty.sql, Wykonaj. Plik tworzy jedną tabelę z Obrazu 1 - szczyty z kolumnami id, pasmo, nazwa i wysokosc - i wpisuje do niej 26 szczytów, od Mędralowej w Beskidzie Makowskim po Rysy w Tatrach.

    Po imporcie zielony komunikat „Import zakończył się sukcesem” i tabela szczyty w lewym panelu - to są „elementy wskazujące na poprawnie wykonany import”. Zrzut całego ekranu (Print Screen, wklejenie do edytora grafiki) zapisujesz jako import.jpg.

    Typowe błędy

    Ten zrzut ma być w JPEG (import.jpg), a zrzuty zapytań - w PNG. Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).

    Podgląd strony po tym kroku
    Podgląd strony po kroku 3
  4. Krok 4: Zapytanie 1: szczyty wyższe niż 1500 m

    Kryteria: ,

    R.1.2 Zapisano plik tekstowy o nazwie kwerendy zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania

    R.1.3 Utworzono zapytanie 1 wybierające jedynie pola nazwa i pasmo z tabeli szczyty dla szczytów wyższych niż 1500 m. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, pasmo FROM szczyty WHERE wysokosc > 1500; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczne są dokładnie 3 rekordy: Babia Góra (Diablak), Beskid Żywiecki; Śnieżka, Karkonosze; Rysy, Tatry

    ok. 3 min
    Polecenie z arkusza

    Wykonaj zapytania SQL działające na bazie gory. Zapytania zapisz w pliku kwerendy.txt. Wykonaj zrzuty ekranu przedstawiające wyniki działania kwerend. Zrzuty zapisz w formacie PNG i nadaj im nazwy kw1, kw2, kw3, kw4. Zrzuty powinny obejmować cały ekran monitora z widocznym paskiem zadań. Zapytanie 1: wybierające jedynie pola nazwa i pasmo z tabeli szczyty dla szczytów wyższych niż 1500 m

    Zaznacz bazę gory, karta SQL. Zapytanie klauzula po klauzuli:

    • SELECT nazwa, pasmo - „jedynie” te dwa pola, w kolejności z arkusza,
    • FROM szczyty - jedyna tabela w bazie,
    • WHERE wysokosc > 1500 - „wyższe niż” to większe niż, bez równości. Wysokość jest zapisana w metrach jako liczba całkowita, więc w warunku stoi sama liczba, bez jednostki.

    Wynik: 3 rekordy - Babia Góra (Diablak) z Beskidu Żywieckiego, Śnieżka z Karkonoszy i Rysy z Tatr, dokładnie jak w kluczu. Zapytanie kopiujesz do pliku kwerendy.txt, a zrzut całego ekranu z wynikiem zapisujesz jako kw1.png.

    Typowe błędy

    SELECT * wybiera też id i wysokosc - arkusz mówi „jedynie pola nazwa i pasmo”. Zapytanie ma działać dla każdego zestawu danych, więc nie wolno wybierać szczytów po id ani po nazwie.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT nazwa, pasmo FROM szczyty WHERE wysokosc > 1500;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: nazwa najwyższego szczytu

    Kryteria:

    R.1.4 Utworzono zapytanie 2 wybierające jedynie nazwę najwyższego szczytu w tabeli szczyty . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa FROM szczyty ORDER BY wysokosc DESC LIMIT 1; (Uwaga! Zapytanie można zapisać na kilka sposobów - ważny jest rezultat wykonania) oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczna jest jedynie nazwa Rysy

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie nazwę najwyższego szczytu w tabeli szczyty

    • SELECT nazwa FROM szczyty - tylko nazwa,
    • ORDER BY wysokosc DESC - sortowanie od najwyższego (DESC = malejąco),
    • LIMIT 1 - z posortowanej listy zostaje pierwszy wiersz.

    Wynik: Rysy (2499 m), sama nazwa - jak w kluczu. Ten sam wynik daje podzapytanie WHERE wysokosc = (SELECT MAX(wysokosc) FROM szczyty) - sprawdzone; klucz przyjmuje każdy zapis, który zwraca tylko Rysy. Zrzut: kw2.png.

    Typowe błędy

    SELECT nazwa, MAX(wysokosc) FROM szczyty zwraca największą wysokość, ale nazwę z dowolnego wiersza (w MariaDB zwykle z pierwszego, czyli Mędralowa) - do tego dwie kolumny zamiast jednej.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, pasmo FROM szczyty WHERE wysokosc > 1500;
    
    -- Zapytanie 2
    SELECT nazwa FROM szczyty ORDER BY wysokosc DESC LIMIT 1;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: użytkownik leon

    Kryteria:

    R.1.5 Utworzono zapytanie 3 tworzące użytkownika leon@localhost z hasłem Leon%Zawodowiec W pliku z kwerendami lub na zrzucie istnieje zapis z jawnym hasłem, np.: CREATE USER 'leon'@'localhost' IDENTIFIED BY 'Leon%Zawodowiec'; oraz wynik działania zapytania udokumentowano zrzutem, wskazującym na poprawne założenie konta użytkownika

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: tworzące użytkownika leon@localhost z hasłem Leon%Zawodowiec

    • CREATE USER - nowe konto serwera bazy danych,
    • 'leon'@'localhost' - nazwa i komputer, z którego wolno się logować; obie części w apostrofach, połączone znakiem @,
    • IDENTIFIED BY 'Leon%Zawodowiec' - hasło zapisane jawnie, wielkość liter ma znaczenie; serwer sam zapisze je w postaci zaszyfrowanej.

    phpMyAdmin odpowiada „MySQL zwrócił pusty wynik” - CREATE USER niczego nie wybiera, więc to znak sukcesu. Zrzut: kw3.png.

    Typowe błędy

    Znak % w nazwie hosta oznacza „dowolny komputer” ('leon'@'%'), ale w haśle jest zwykłym znakiem - byle hasło stało w apostrofach. Konto utworzone kreatorem zamiast zapytaniem nie zostawia zapytania do pliku ani na zrzucie.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, pasmo FROM szczyty WHERE wysokosc > 1500;
    
    -- Zapytanie 2
    SELECT nazwa FROM szczyty ORDER BY wysokosc DESC LIMIT 1;
    
    -- Zapytanie 3
    CREATE USER 'leon'@'localhost' IDENTIFIED BY 'Leon%Zawodowiec';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: prawa do manipulowania danymi w bazie gory

    Kryteria:

    R.1.6 Utworzono zapytanie 4 Nadające użytkownikowi leon@localhost jedynie wszystkie prawa do manipulowania danymi we wszystkich tabelach bazy gory . W pliku z kwerendami lub na zrzucie istnieje zapis np.: GRANT UPDATE, DELETE, INSERT ON gory.* TO 'leon'@'localhost'; (możliwe też gory.szczyty - zamiast gwiazdki; opcjonalnie może być też SELECT) oraz wynik działania zapytania udokumentowano zrzutem wskazującym na poprawnie nadane prawa

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 4: Nadające użytkownikowi leon@localhost jedynie wszystkie prawa do manipulowania danymi we wszystkich tabelach bazy gory

    Prawa do manipulowania danymi to operacje na rekordach: dodawanie - INSERT, zmiana - UPDATE, usuwanie - DELETE, a także odczyt - SELECT. „Jedynie” wyklucza prawa do zmiany budowy bazy (CREATE, ALTER, DROP) i do zarządzania kontami. Dalej:

    • ON gory.* - wszystkie tabele (*) bazy gory,
    • TO 'leon'@'localhost' - konto z zapytania 3, zapisane tak samo.

    Przykład w kluczu ma tylko UPDATE, DELETE, INSERT i dopuszcza dopisanie SELECT. Tutaj SELECT jest, bo bez niego prawa działają tylko połowicznie - sprawdzone logowaniem na konto leon: przy prawach z przykładu z klucza zapytanie DELETE FROM szczyty WHERE id = 26 kończy się błędem „SELECT command denied to user 'leon'@'localhost' for column 'id' in table 'szczyty'”, bo warunek WHERE musi odczytać kolumnę id. Z prawem SELECT dodanie, zmiana i usunięcie rekordu działają, a DROP TABLE kończy się odmową. Komunikat „MySQL zwrócił pusty wynik”, zrzut kw4.png.

    Typowe błędy

    GRANT ALL PRIVILEGES daje też prawo do usuwania tabel i całej bazy - arkusz mówi „jedynie” o danych. ON *.* nadaje prawa do wszystkich baz serwera.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, pasmo FROM szczyty WHERE wysokosc > 1500;
    
    -- Zapytanie 2
    SELECT nazwa FROM szczyty ORDER BY wysokosc DESC LIMIT 1;
    
    -- Zapytanie 3
    CREATE USER 'leon'@'localhost' IDENTIFIED BY 'Leon%Zawodowiec';
    
    -- Zapytanie 4
    GRANT SELECT, INSERT, UPDATE, DELETE ON gory.* TO 'leon'@'localhost';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Krok 8: SHOW GRANTS z pełnymi tekstami i zrzut grants.png

    Kryteria:

    R.1.7 W pliku grants.png widoczne są przydzielone prawa dla użytkownika leon dla tabel bazy gory

    ok. 2 min
    Polecenie z arkusza

    Wykonanie zapytania 3 oraz 4 należy dodatkowo udokumentować obrazem o nazwie grants.png, na którym jest widoczny efekt wywołania polecenia SHOW GRANTS FOR ‘leon’@’localhost’;. Uwaga: należy zaznaczyć opcję „Pełne teksty” nad wyświetlanymi prawami

    W arkuszu polecenie jest wydrukowane z apostrofami drukarskimi (‘leon’) - w karcie SQL wpisz zwykłe apostrofy z klawiatury: SHOW GRANTS FOR 'leon'@'localhost';. Wynik to dwa wiersze:

    • GRANT USAGE ON *.* TOleon@localhostIDENTIFIED … - samo prawo do logowania (USAGE = brak praw do danych) i skrót hasła,
    • GRANT SELECT, INSERT, UPDATE, DELETE ONgory.* TOleon@localhost`` - prawa z zapytania 4.

    phpMyAdmin skraca długie wartości w wynikach. Nad tabelą wyników rozwiń + Opcje, zaznacz Pełne teksty i kliknij Wykonaj - dopiero wtedy cały wiersz z prawami jest widoczny. Zrzut całego ekranu: grants.png. Polecenia SHOW GRANTS nie dopisujesz do kwerendy.txt - arkusz wymienia tam zapytania 1-4.

    Typowe błędy

    Apostrofy skopiowane z arkusza (‘ ’) kończą się błędem składni. Zrzut z uciętym wierszem praw (bez „Pełne teksty”) nie pokazuje, do których tabel leon ma prawa.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Etap 2: Grafika i strona HTML

    Kroki 9-28 · po tym etapie masz 19 z 38 kryteriów (pkt)

    Krok 9: Kadrowanie: zamek i fragment gór w pionie

    ok. 3 min
    Polecenie z arkusza

    Plik zdjecie.jpg, wypakowany z archiwum, należy wykadrować tak, aby był widoczny zamek oraz fragment gór. Po wykadrowaniu obraz ma orientację pionową.

    zdjecie.jpg ma 640 × 426 px - jest poziome. Zamek stoi na wzgórzu nieco na lewo od środka, a nad mgłą widać ośnieżone Tatry. Kadr ma objąć zamek i kawałek gór nad nim, a po przycięciu być wyższy niż szerszy (orientacja pionowa).

    W GIMP-ie: narzędzie Kadrowanie (Shift+C), w opcjach narzędzia pozycja 60 × 1 i rozmiar 300 × 424, Enter. Żółta ramka na podglądzie pokazuje ten kadr na oryginale: zamek w dolnej części, nad nim mgła i szczyty.

    Typowe błędy

    Kadr wąski, ale bez zamku albo bez gór, nie spełnia R.2.1 - klucz sprawdza oba elementy i orientację pionową.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 9
  10. Krok 10: Kadr 300 × 424 px i zapis zdjecie.jpg

    Kryteria:

    R.2.1 Plik zdjecie .jpg wykadrowano tak, aby był widoczny zamek oraz fragment gór. Po wykadrowaniu obraz ma orientację pionową

    ok. 2 min
    Polecenie z arkusza

    Przykład wykadrowania znajduje się po lewej stronie obrazu 2. Wymiary obrazu użytego w panelu lewym wynoszą 300 px na 424 px. Skadrowany obraz powinien mieć zbliżone wymiary.

    Wysokość oryginału to 426 px, więc kadr 300 × 424 px mieści się w nim bez skalowania - wystarczy samo przycięcie, bez utraty jakości. Wynik: dokładnie 300 × 424 px, jak obraz w arkuszu.

    Zapis pod tą samą nazwą: Plik → Zastąp zdjecie.jpg (albo Wyeksportuj jako… z nazwą zdjecie.jpg i potwierdzeniem zastąpienia). Arkusz każe nagrać na płytę plik zdjecie.jpg, a strona będzie go wyświetlać - w folderze ma zostać wersja wykadrowana.

    Typowe błędy

    Zwykłe Zapisz w GIMP-ie zapisuje projekt w formacie .xcf - strona go nie wyświetli. Zapisanie kadru pod inną nazwą (np. zdjecie2.jpg) zostawia w folderze nieprzycięty zdjecie.jpg.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 10
  11. Krok 11: Plik galeria.html

    Kryteria:

    R.2.2 Witrynę internetową zapisano w pliku o nazwie galeria.html

    ok. 1 min
    Polecenie z arkusza

    Cechy witryny: Składa się ze strony o nazwie galeria.html

    W edytorze tworzysz w folderze zdającego, obok zdjęć, plik galeria.html. Nazwę sprawdza klucz (R.2.2). Plik jest na razie pusty.

    galeria.html HTML nowy plik
    Podgląd strony po tym kroku (galeria.html)
  12. Krok 12: Szkielet HTML5

    ok. 1 min
    Polecenie z arkusza

    Zapisana w języku HTML5

    Pierwsza linia <!DOCTYPE html> to deklaracja HTML5. Pod nią szkielet: <html>, w nim <head> (informacje o stronie) i <body> (to, co widać).

    galeria.html HTML zmienione: 7 linii
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  13. Krok 13: Kodowanie polskich znaków

    ok. 1 min
    Polecenie z arkusza

    Jawnie zastosowano właściwy standard kodowania polskich znaków

    <meta charset="UTF-8"> jako pierwsza rzecz w <head>. Plik trzeba też zapisać w UTF-8 (w Notepad++ menu Kodowanie), inaczej „Galeria obrazów” i „Zdjęcia opublikowali” wyświetlą się z krzakami.

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  14. Krok 14: Język strony

    Kryteria:

    R.2.3 Zastosowano deklarację języka HTML5, jawnie zapisany standard kodowania polskich znaków oraz zadeklarowano język witryny (np. <html lang = 'pl'>)

    ok. 1 min
    Polecenie z arkusza

    Zadeklarowany język zawartości witryny: polski

    Atrybut lang="pl" w znaczniku <html>. Deklaracja HTML5, kodowanie i język razem dają R.2.3.

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  15. Krok 15: Tytuł strony

    Kryteria:

    R.2.4 Nadano tytuł stronie: "Galeria"

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Galeria”

    <title> w <head> - napis na karcie przeglądarki. Nagłówek banera („Galeria obrazów”) to co innego.

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  16. Krok 16: Podpięcie arkusza stylów styl2.css

    Kryteria:

    R.3.5 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl2.css , formatowanie pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy zdający źle przypisał co najmniej jeden selektor do bloku (np. kropka zamiast #)

    ok. 1 min
    Polecenie z arkusza

    Arkusz stylów w pliku o nazwie styl2.css prawidłowo połączony z kodem strony

    <link rel="stylesheet" href="styl2.css"> w <head>. Plik stylów powstanie po HTML-u; całe formatowanie strony będzie w nim (R.3.5).

    Typowe błędy

    Klucz uznaje R.3.5 tylko przy działającym połączeniu, w którym każdy selektor trafia w swój blok - kropka zamiast # przy identyfikatorze odbiera punkt.

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  17. Krok 17: Bloki: baner, lewy, prawy i stopka

    Kryteria:

    R.2.5 Wygląd strony zdefiniowano dzieląc ją na bloki: baner, lewy i prawy, stopka. Zastosowano znaczniki sekcji

    ok. 2 min
    Polecenie z arkusza

    Podział strony na: blok banera, obok siebie bloki lewy i prawy, stopka. Podział zrealizowany za pomocą znaczników sekcji tak, aby wygląd układu bloków strony po uruchomieniu w przeglądarce, był zgodny z Obrazem 2

    Cztery bloki w kolejności z obrazu 2: baner <header>, blok lewy i prawy jako <section>, stopka <footer>. Sekcje różnią się wymiarami, więc dostają identyfikatory left i right (nazwy po angielsku - arkusz ich nie narzuca). Obok siebie ustawi je dopiero CSS.

    galeria.html HTML zmienione: 8 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
        </header>
        <section id="left">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  18. Krok 18: Baner: nagłówek pierwszego stopnia

    ok. 1 min
    Polecenie z arkusza

    Zawartość banera: nagłówek pierwszego stopnia o treści „Galeria obrazów”

    <h1> w <header> - jedyny nagłówek pierwszego stopnia na stronie.

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  19. Krok 19: Blok lewy: wykadrowane zdjęcie z tekstem alternatywnym

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku lewego: obraz zdjecie.jpg z tekstem alternatywnym „zdjęcie dnia”

    <img> z atrybutami src="zdjecie.jpg" - wykadrowany plik - i alt z tekstem, który czytnik ekranu przeczyta zamiast obrazu. Na razie zdjęcie ma swoje 300 px szerokości; dopasuje je do bloku dopiero CSS.

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  20. Krok 20: Blok lewy: nagłówek trzeciego stopnia

    ok. 1 min
    Polecenie z arkusza

    nagłówek trzeciego stopnia o treści „Zdjęcia opublikowali”

    Trzeciego stopnia to <h3> - na stronie nie ma nagłówka <h2>, a mimo to arkusz wymaga właśnie trzeciego stopnia.

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  21. Krok 21: Blok lewy: tabela autorów zdjęć

    Kryteria:

    R.2.7 W bloku lewym umieszczono tabelę o trzech wierszach i dwóch kolumnach, zastosowano znaczniki <table>, <tr>, <td>

    ok. 3 min
    Polecenie z arkusza

    tabela o trzech wierszach i dwóch kolumnach wypełniona zgodnie z Obrazem 3

    <table> to tabela, <tr> - jej wiersz, a <td> - komórka. Trzy wiersze po dwie komórki, treść przepisana z obrazu 3: osoba w pierwszej kolumnie, liczba zdjęć w drugiej. Tabela nie ma wiersza nagłówkowego - obraz 3 go nie pokazuje (R.2.7).

    Typowe błędy

    „4 zdjęcia”, a nie „4 zdjęć” - przy przepisywaniu z obrazu łatwo powielić końcówkę z wierszy wyżej. Klucz dopuszcza drobne literówki, ale tabela musi mieć dokładnie trzy wiersze i dwie kolumny.

    galeria.html HTML zmienione: 14 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  22. Krok 22: Blok prawy: przycisk „prev”

    ok. 1 min
    Polecenie z arkusza

    Zawartość prawego bloku: przycisk o treści „prev”, którego kliknięcie uruchamia funkcję skryptu wyświetlającą poprzednie zdjęcie

    <button>prev</button> - napis na przycisku to treść między znacznikami, małymi literami jak w arkuszu. Wywołanie funkcji dojdzie w etapie JavaScript, gdy funkcja będzie już napisana.

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button>prev</button>
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  23. Krok 23: Blok prawy: duże zdjęcie 1.jpg

    Kryteria:

    R.2.8 W bloku lewym umieszczono obraz zdjecie.jpg z tekstem alternatywnym „zdjęcie dnia” oraz w bloku prawym obraz 1.jpg z tekstem alternatywnym „galeria”

    ok. 1 min
    Polecenie z arkusza

    obraz 1.jpg z tekstem alternatywnym „galeria”

    Duże zdjęcie zaczyna od pliku 1.jpg - „aktywne zdjęcie początkowo jest zdjęciem pierwszym”. Dostaje identyfikator photo: po nim CSS ustawi wymiary tylko temu obrazowi, a skrypt znajdzie go metodą getElementById i podmieni plik. Zdjęcia w lewym i prawym bloku mają już swoje teksty alternatywne (R.2.8).

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button>prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  24. Krok 24: Blok prawy: przycisk „next”

    Kryteria:

    R.2.10 W bloku prawym umieszczono dwa przyciski opisane "prev" i "next"

    ok. 1 min
    Polecenie z arkusza

    przycisk o treści „next”, którego kliknięcie uruchamia funkcję skryptu wyświetlającą następne zdjęcie

    Drugi przycisk po zdjęciu. Przyciski i obraz są elementami liniowymi, więc stoją w jednej linii: „prev” po lewej stronie zdjęcia, „next” po prawej - jak na obrazie 2 (R.2.10).

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button>prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
            <button>next</button>
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  25. Krok 25: Blok prawy: linia horyzontalna

    ok. 1 min
    Polecenie z arkusza

    linia horyzontalna

    <hr> rysuje poziomą linię na całą szerokość bloku i zaczyna nową linię - miniatury staną pod nią. To znacznik bez zamknięcia.

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button>prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
            <button>next</button>
            <hr>
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  26. Krok 26: Blok prawy: pięć miniatur

    Kryteria:

    R.2.9 W bloku prawym umieszczono pięć zdjęć 1.jpg ÷ 5.jpg , przynajmniej jedno z nich ma tekst alternatywny "miniatura"

    ok. 2 min
    Polecenie z arkusza

    5 miniatur, kolejno 1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg. Każda miniatura ma tekst alternatywny „miniatura”. Po kliknięciu na miniaturę uruchamia się funkcja skryptu zamieniająca widoczne duże zdjęcie na kliknięte

    Pięć znaczników <img> z tymi samymi plikami co duże zdjęcie, każdy z alt="miniatura" (R.2.9). Miniatury dostają wspólną klasę thumb - arkusz każe ustawić wygląd „jedynie dla miniatur”, a klasa odróżni je od dużego zdjęcia, które też stoi w bloku prawym. Na razie miniatury mają pełny rozmiar zdjęć (360 px); pomniejszy je CSS. Obsługa kliknięcia dojdzie w etapie JavaScript.

    galeria.html HTML zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button>prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
            <button>next</button>
            <hr>
            <img src="1.jpg" alt="miniatura" class="thumb">
            <img src="2.jpg" alt="miniatura" class="thumb">
            <img src="3.jpg" alt="miniatura" class="thumb">
            <img src="4.jpg" alt="miniatura" class="thumb">
            <img src="5.jpg" alt="miniatura" class="thumb">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  27. Krok 27: Stopka: odnośnik otwierany w nowej karcie

    Kryteria:

    R.3.2 Na stronie umieszczono odnośnik, którego kliknięcie inicjuje otwarcie strony https://pixabay.com w nowej karcie przeglądarki

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku stopki: odnośnik do strony https://pixabay.com otwierany w nowej karcie przeglądarki i podpisany „Więcej obrazów”

    <a href="https://pixabay.com"> z adresem dokładnie jak w arkuszu, a target="_blank" otwiera stronę w nowej karcie (R.3.2). Pixabay to serwis z darmowymi zdjęciami - stąd pochodzą zdjęcia galerii.

    Typowe błędy

    href="pixabay.com" bez https:// przeglądarka potraktuje jako plik w folderze strony i pokaże błąd.

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button>prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
            <button>next</button>
            <hr>
            <img src="1.jpg" alt="miniatura" class="thumb">
            <img src="2.jpg" alt="miniatura" class="thumb">
            <img src="3.jpg" alt="miniatura" class="thumb">
            <img src="4.jpg" alt="miniatura" class="thumb">
            <img src="5.jpg" alt="miniatura" class="thumb">
        </section>
        <footer>
            <a href="https://pixabay.com" target="_blank">Więcej obrazów</a>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  28. Krok 28: Stopka: paragraf z autorem galerii

    Kryteria:

    R.2.6 W bloku banera zapisano nagłówek h1: "Galeria obrazów", w bloku lewym - h3: "Zdjęcia opublikowali", w bloku stopki paragraf: „Galerię wykonał: "

    ok. 1 min
    Polecenie z arkusza

    paragraf o treści „Galerię wykonał: ”, dalej wstawiony numer zdającego

    Na egzaminie po dwukropku wpisujesz swój numer PESEL. W tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora: Bartosz Bryniarski. Strona ma już nagłówki <h1>, <h3> i paragraf w stopce (R.2.6).

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button>prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
            <button>next</button>
            <hr>
            <img src="1.jpg" alt="miniatura" class="thumb">
            <img src="2.jpg" alt="miniatura" class="thumb">
            <img src="3.jpg" alt="miniatura" class="thumb">
            <img src="4.jpg" alt="miniatura" class="thumb">
            <img src="5.jpg" alt="miniatura" class="thumb">
        </section>
        <footer>
            <a href="https://pixabay.com" target="_blank">Więcej obrazów</a>
            <p>Galerię wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  29. Etap 3: Styl CSS

    Kroki 29-39 · po tym etapie masz 30 z 38 kryteriów (pkt)

    Krok 29: Plik styl2.css: Garamond i wyśrodkowanie dla wszystkich

    Kryteria:

    R.4.1 Ustawiono domyślne wartości dla selektorów (*): krój czcionki Garamond, wyrównanie tekstu do środka

    ok. 1 min
    Polecenie z arkusza

    Styl CSS powinien być zdefiniowany jedynie w zewnętrznym pliku CSS. Ustawione domyślne wartości dla wszystkich selektorów stylu CSS: krój czcionki Garamond, kolor tła MistyRose, kolor czcionki RGB: 62, 39,35; wyrównanie tekstu do środka

    Nowy plik styl2.css w folderze zdającego - od teraz każda reguła trafia tylko tutaj, bez atrybutów style w HTML-u. „Dla wszystkich selektorów” to selektor uniwersalny *: obejmuje każdy element, także przyciski, które kroju po body nie dziedziczą. Najpierw krój i wyrównanie (R.4.1), kolory w następnym kroku.

    Garamond to krój szeryfowy, który jest w Windows z pakietem Office. Gdy go brak, przeglądarka użyje domyślnego kroju szeryfowego.

    styl2.css CSS nowy plik
    * {
        font-family: Garamond;
        text-align: center;
    }
    Podgląd strony po tym kroku (galeria.html)
  30. Krok 30: Kolor tła MistyRose i kolor czcionki RGB

    Kryteria:

    R.4.2 Ustawiono domyślne wartości dla selektorów (*): kolor tła MistyRose, kolor czcionki rgb(62, 39, 35)

    ok. 1 min
    Polecenie z arkusza

    Ustawione domyślne wartości dla wszystkich selektorów stylu CSS: krój czcionki Garamond, kolor tła MistyRose, kolor czcionki RGB: 62, 39,35; wyrównanie tekstu do środka

    Do tej samej reguły *: background-color: MistyRose (nazwa koloru CSS - jasny róż) i color: rgb(62, 39, 35) - kolor zapisany trzema składowymi czerwonej, zielonej i niebieskiej, od 0 do 255; tu ciemny brąz (R.4.2).

    Tło ustawione dla * dostaje każdy element, także przyciski i komórki tabeli - dlatego na obrazie 2 przyciski „prev” i „next” są różowe, a nie szare.

    Typowe błędy

    color: RGB 62, 39, 35 albo rgb(62 39 35) z przecinkami w złych miejscach przeglądarka odrzuci po cichu - zapis to rgb(62, 39, 35).

    styl2.css CSS zmienione: 2 linie
    * {
        font-family: Garamond;
        background-color: MistyRose;
        color: rgb(62, 39, 35);
        text-align: center;
    }
    Podgląd strony po tym kroku (galeria.html)
  31. Krok 31: Blok lewy: szerokość, wysokość i marginesy zewnętrzne

    ok. 1 min
    Polecenie z arkusza

    Dla bloku lewego: szerokość 20%, wysokość 600 px, marginesy zewnętrzne 30 px, cień bloku z przesunięciem równym 15 px w poziomie i pionie, rozmycie 10 px i kolor DimGray, w przypadku, gdy zawartość bloku nie mieści się dodawane są paski przewijania

    Selektor identyfikatora #left. Szerokość w procentach liczy się od szerokości okna, wysokość jest stała, a margin: 30px odsuwa blok o 30 px od banera, od krawędzi okna i od bloku prawego. Cień i paski przewijania - w następnym kroku.

    styl2.css CSS zmienione: 5 linii
    * {
        font-family: Garamond;
        background-color: MistyRose;
        color: rgb(62, 39, 35);
        text-align: center;
    }
    #left {
        width: 20%;
        height: 600px;
        margin: 30px;
    }
    Podgląd strony po tym kroku (galeria.html)
  32. Krok 32: Blok lewy: cień i paski przewijania

    Kryteria:

    R.4.6 Ustawiono dla bloku lewego lub dla dużego obrazu z bloku prawego cień o cechach: oba przesunięcia 15 px, rozmycie 10px, kolor DimGray, np. box-shadow: 15px 15px 10px DimGray (lub 15px 15px 10px 0 DimGray)

    ok. 2 min
    Polecenie z arkusza

    Dla bloku lewego: szerokość 20%, wysokość 600 px, marginesy zewnętrzne 30 px, cień bloku z przesunięciem równym 15 px w poziomie i pionie, rozmycie 10 px i kolor DimGray, w przypadku, gdy zawartość bloku nie mieści się dodawane są paski przewijania

    • box-shadow: 15px 15px 10px DimGray - kolejność wartości z pomocy w3schools na końcu arkusza: przesunięcie w poziomie (dodatnie = w prawo), w pionie (dodatnie = w dół), rozmycie i kolor. Cień wychodzi spod bloku w prawo i w dół (R.4.6).
    • overflow: auto - paski przewijania pojawiają się tylko wtedy, gdy zawartość nie mieści się w 600 px; scroll pokazywałby je zawsze.

    Zmierzone w Chrome: w oknie 1280 px zdjęcie, nagłówek i tabela zajmują ok. 485 px i mieszczą się w bloku. W oknie 1920 px blok jest szerszy, zdjęcie (szerokość 100%) robi się wyższe i tabela kończy się ok. 65 px poniżej dolnej krawędzi - wtedy pojawia się pionowy pasek przewijania, dokładnie na taki przypadek.

    Typowe błędy

    box-shadow: 15px 15px DimGray 10px (rozmycie po kolorze) jest błędem składni - przeglądarka pominie całą deklarację i cienia nie będzie.

    styl2.css CSS zmienione: 2 linie
    * {
        font-family: Garamond;
        background-color: MistyRose;
        color: rgb(62, 39, 35);
        text-align: center;
    }
    #left {
        width: 20%;
        height: 600px;
        margin: 30px;
        box-shadow: 15px 15px 10px DimGray;
        overflow: auto;
    }
    Podgląd strony po tym kroku (galeria.html)
  33. Krok 33: Zdjęcie w bloku lewym: szerokość 100%

    ok. 1 min
    Polecenie z arkusza

    Dla selektora obrazu umieszczonego jedynie w bloku lewym: szerokość 100%

    #left img to selektor potomka: spacja między częściami znaczy „obraz wewnątrz bloku o identyfikatorze left”. Duże zdjęcie i miniatury w bloku prawym tej reguły nie dostaną. width: 100% dopasowuje zdjęcie do szerokości bloku, a wysokość przelicza się sama z zachowaniem proporcji.

    Uwaga w arkuszu każe ustawić ten styl selektorem znacznika obrazu z bloku lewego, a nie klasą - #left img spełnia to dokładnie.

    Typowe błędy

    Sam selektor img zmieni wszystkie obrazy na stronie, a klasa (np. .left-photo) jest sprzeczna z uwagą w arkuszu - w obu przypadkach klucz nie uznaje R.4.7.

    styl2.css CSS zmienione: 3 linie
    * {
        font-family: Garamond;
        background-color: MistyRose;
        color: rgb(62, 39, 35);
        text-align: center;
    }
    #left {
        width: 20%;
        height: 600px;
        margin: 30px;
        box-shadow: 15px 15px 10px DimGray;
        overflow: auto;
    }
    #left img {
        width: 100%;
    }
    Podgląd strony po tym kroku (galeria.html)
  34. Krok 34: Blok prawy: szerokość i wysokość

    Kryteria: ,

    R.4.3 Ustawiono wysokość 600px dla bloku lewego i prawego

    R.4.4 Ustawiono szerokość 20% dla bloku lewego i 65% dla bloku prawego (width lub grid- template-columns lub flex)

    ok. 1 min
    Polecenie z arkusza

    Dla bloku prawego: szerokość 65%, wysokość 600 px

    Selektor #right. Obie sekcje mają już wysokość 600 px (R.4.3), a szerokości 20% i 65% (R.4.4).

    styl2.css CSS zmienione: 4 linie
    * {
        font-family: Garamond;
        background-color: MistyRose;
        color: rgb(62, 39, 35);
        text-align: center;
    }
    #left {
        width: 20%;
        height: 600px;
        margin: 30px;
        box-shadow: 15px 15px 10px DimGray;
        overflow: auto;
    }
    #left img {
        width: 100%;
    }
    #right {
        width: 65%;
        height: 600px;
    }
    Podgląd strony po tym kroku (galeria.html)
  35. Krok 35: Układ bloków zgodny z obrazem 2

    Kryteria:

    R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z Obrazem 2 w arkuszu egzaminacyjnym (prawidłowo zastosowano właściwości CSS układające bloki na stronie, np. float i clear albo display flex albo grid)

    ok. 2 min
    Polecenie z arkusza

    Podział strony na: blok banera, obok siebie bloki lewy i prawy, stopka. Podział zrealizowany za pomocą znaczników sekcji tak, aby wygląd układu bloków strony po uruchomieniu w przeglądarce, był zgodny z Obrazem 2

    Obie sekcje dostają float: left: blok lewy (20% + po 30 px marginesu z każdej strony) staje przy lewej krawędzi, prawy (65%) obok niego. Razem zajmują mniej niż całe okno, więc po prawej zostaje wolny pas tła - tak jak na obrazie 2. Stopka z clear: both zaczyna się pod blokami, a nie obok nich (R.3.1).

    Zmierzone w Chrome przy oknie 1280 px: blok lewy ma 248 px szerokości i 600 px wysokości, prawy 807 px - stoją obok siebie. Górna krawędź bloku lewego wypada na tej samej wysokości co duże zdjęcie (oba mają margines 30 px), jak na obrazie 2, a stopka zaczyna się pod marginesem bloku lewego.

    Typowe błędy

    Bez clear: both stopka wsuwa się pod pływające bloki i jej tekst ląduje obok nich, przy prawej krawędzi okna.

    styl2.css CSS zmienione: 6 linii
    * {
        font-family: Garamond;
        background-color: MistyRose;
        color: rgb(62, 39, 35);
        text-align: center;
    }
    #left {
        width: 20%;
        height: 600px;
        margin: 30px;
        box-shadow: 15px 15px 10px DimGray;
        overflow: auto;
    }
    #left img {
        width: 100%;
    }
    #right {
        width: 65%;
        height: 600px;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    Podgląd strony po tym kroku (galeria.html)
  36. Krok 36: Miniatury: szerokość, marginesy wewnętrzne i zaokrąglenie

    Kryteria:

    R.4.8 Ustawiono zaokrąglenie rogów (border-radius) 5% jedynie dla miniatur oraz paski przewijania w przypadku przepełnienia bloku lewego (overflow: auto;)

    ok. 2 min
    Polecenie z arkusza

    Jedynie dla miniatur: szerokość 140 px, marginesy wewnętrzne 2 px, zaokrąglenie rogów 5%.

    Selektor klasy .thumb - z kropką, bo w HTML-u jest class="thumb". Klasę mają tylko miniatury, więc duże zdjęcie zostaje bez zmian („jedynie dla miniatur”).

    • width: 140px - wysokość przelicza się sama (zdjęcia 360 × 240 dają ok. 93 px),
    • padding: 2px - margines wewnętrzny między zdjęciem a ramką, która pojawi się pod kursorem,
    • border-radius: 5% - zaokrąglenie rogów liczone od wymiarów obrazu; jedynie miniatury mają zaokrąglone rogi, a blok lewy ma przewijanie z poprzedniego kroku (R.4.8).
    styl2.css CSS zmienione: 5 linii
    * {
        font-family: Garamond;
        background-color: MistyRose;
        color: rgb(62, 39, 35);
        text-align: center;
    }
    #left {
        width: 20%;
        height: 600px;
        margin: 30px;
        box-shadow: 15px 15px 10px DimGray;
        overflow: auto;
    }
    #left img {
        width: 100%;
    }
    #right {
        width: 65%;
        height: 600px;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    .thumb {
        width: 140px;
        padding: 2px;
        border-radius: 5%;
    }
    Podgląd strony po tym kroku (galeria.html)
  37. Krok 37: Miniatura pod kursorem: ramka kropkowa

    Kryteria:

    R.4.9 Ustawiono pseudoklasę hover dla miniatur. Gdy kursor znajdzie się na miniaturze pojawia się ramka o szerokości 1 px, czarną linią kropkową (dotted)

    ok. 1 min
    Polecenie z arkusza

    Gdy kursor znajdzie się na miniaturze pojawia się ramka o szerokości 1 px, czarną linią kropkową

    Pseudoklasa :hover działa tylko wtedy, gdy kursor jest nad miniaturą. border: 1px dotted black - szerokość, linia kropkowa (dotted; kreskowa to dashed), kolor (R.4.9). W podglądzie najedź kursorem na dowolną miniaturę.

    Typowe błędy

    Ramka pojawiająca się pod kursorem dokłada po 1 px z każdej strony, więc pozostałe miniatury przesuwają się o 2 px - tak działa wersja z arkusza. Spacja w .thumb :hover zmienia znaczenie selektora i reguła przestaje działać.

    styl2.css CSS zmienione: 3 linie
    * {
        font-family: Garamond;
        background-color: MistyRose;
        color: rgb(62, 39, 35);
        text-align: center;
    }
    #left {
        width: 20%;
        height: 600px;
        margin: 30px;
        box-shadow: 15px 15px 10px DimGray;
        overflow: auto;
    }
    #left img {
        width: 100%;
    }
    #right {
        width: 65%;
        height: 600px;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    .thumb {
        width: 140px;
        padding: 2px;
        border-radius: 5%;
    }
    .thumb:hover {
        border: 1px dotted black;
    }
    Podgląd strony po tym kroku (galeria.html)
  38. Krok 38: Duże zdjęcie: szerokość, marginesy i cień

    Kryteria: ,

    R.4.5 Ustawiono marginesy zewnętrzne (margin) 30px dla bloku lewego, 30px dla dużego obrazu w bloku prawym i marginesy wewnętrzne (padding) 2px dla miniatur

    R.4.7 Ustawiono szerokość 100% dla selektora img umieszczonego jedynie w bloku lewym np. z użyciem selektora dziecka lub potomka, 500px dla dużego obrazu z bloku prawego oraz 140px dla miniatur

    ok. 2 min
    Polecenie z arkusza

    Jedynie dla dużego obrazu z bloku prawego: szerokość 500 px, marginesy zewnętrzne 30 px, cień bloku z przesunięciem równym 15 px w poziomie i pionie, rozmycie 10 px i kolor DimGray

    Selektor identyfikatora #photo trafia tylko w duże zdjęcie. Cień jest ten sam co przy bloku lewym. Marginesy 30 px odsuwają zdjęcie od przycisków po bokach i od górnej krawędzi bloku. Komplet marginesów (30 px bloku lewego i dużego zdjęcia, 2 px miniatur - R.4.5) i szerokości obrazów (100%, 500 px, 140 px - R.4.7) jest ustawiony.

    Przyciski stoją w linii z obrazem, więc ich dolna krawędź wyrównuje się do dolnego marginesu zdjęcia - dlatego na obrazie 2 „prev” i „next” są nieco poniżej zdjęcia.

    styl2.css CSS zmienione: 5 linii
    * {
        font-family: Garamond;
        background-color: MistyRose;
        color: rgb(62, 39, 35);
        text-align: center;
    }
    #left {
        width: 20%;
        height: 600px;
        margin: 30px;
        box-shadow: 15px 15px 10px DimGray;
        overflow: auto;
    }
    #left img {
        width: 100%;
    }
    #right {
        width: 65%;
        height: 600px;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    .thumb {
        width: 140px;
        padding: 2px;
        border-radius: 5%;
    }
    .thumb:hover {
        border: 1px dotted black;
    }
    #photo {
        width: 500px;
        margin: 30px;
        box-shadow: 15px 15px 10px DimGray;
    }
    Podgląd strony po tym kroku (galeria.html)
  39. Krok 39: Tabela: obramowanie kreskowe i szerokość 100%

    Kryteria:

    R.4.10 Ustawiono dla selektora tabeli obramowanie o szerokości 1 px, czarną linią kreskową (dashed) oraz szerokość 100%

    ok. 1 min
    Polecenie z arkusza

    Dla selektora tabeli: obramowanie o szerokości 1 px, czarną linią kreskową, szerokość 100%

    Selektor znacznika table - zgodnie z uwagą w arkuszu, bez klasy. Linia kreskowa to dashed. Obramowanie ma tylko tabela, komórki zostają bez linii - tak wygląda obraz 3 (R.4.10).

    Typowe błędy

    table, td obramuje też każdą komórkę - obraz 3 ma tylko ramkę zewnętrzną.

    styl2.css CSS zmienione: 4 linie
    * {
        font-family: Garamond;
        background-color: MistyRose;
        color: rgb(62, 39, 35);
        text-align: center;
    }
    #left {
        width: 20%;
        height: 600px;
        margin: 30px;
        box-shadow: 15px 15px 10px DimGray;
        overflow: auto;
    }
    #left img {
        width: 100%;
    }
    #right {
        width: 65%;
        height: 600px;
    }
    section {
        float: left;
    }
    footer {
        clear: both;
    }
    .thumb {
        width: 140px;
        padding: 2px;
        border-radius: 5%;
    }
    .thumb:hover {
        border: 1px dotted black;
    }
    #photo {
        width: 500px;
        margin: 30px;
        box-shadow: 15px 15px 10px DimGray;
    }
    table {
        border: 1px dashed black;
        width: 100%;
    }
    Podgląd strony po tym kroku (galeria.html)
  40. Etap 4: JavaScript

    Kroki 40-45 · po tym etapie masz 38 z 38 kryteriów (pkt)

    Krok 40: Skrypt i zmienna z numerem aktywnego zdjęcia

    Kryteria:

    R.5.1 Skrypt zapisano w języku JavaScript i zawarto w nim przynajmniej jedną poprawną składniowo instrukcję języka

    ok. 2 min
    Polecenie z arkusza

    Napisany w języku JavaScript. Składa się z trzech funkcji obsługujących wyświetlanie dużego zdjęcia w bloku prawym, zwanego dalej aktywnym zdjęciem oraz zmiennej liczbowej przechowującej numer aktywnego zdjęcia

    Skrypt w znaczniku <script> na końcu <body> - przeglądarka czyta go, gdy duże zdjęcie i przyciski już istnieją. Pierwsza linia to zmienna activePhoto z wartością 1: aktywne zdjęcie początkowo jest pierwsze, a w HTML-u duże zdjęcie ma już src="1.jpg". Zmienna jest zadeklarowana poza funkcjami, więc wszystkie trzy funkcje będą z niej korzystać i pamięta wartość między kliknięciami (R.5.1).

    galeria.html HTML zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button>prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
            <button>next</button>
            <hr>
            <img src="1.jpg" alt="miniatura" class="thumb">
            <img src="2.jpg" alt="miniatura" class="thumb">
            <img src="3.jpg" alt="miniatura" class="thumb">
            <img src="4.jpg" alt="miniatura" class="thumb">
            <img src="5.jpg" alt="miniatura" class="thumb">
        </section>
        <footer>
            <a href="https://pixabay.com" target="_blank">Więcej obrazów</a>
            <p>Galerię wykonał: Bartosz Bryniarski</p>
        </footer>
        <script>
            let activePhoto = 1;
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  41. Krok 41: Funkcja „next”: następne zdjęcie

    Kryteria: ,

    R.3.3 Dla dowolnego przycisku zdefiniowano obsługę zdarzenia kliknięcia (atrybut onClick lub słuchacz zdarzenia click, lub właściwość onclick obiektu DOM)

    R.5.2 Zapisano w skrypcie przynajmniej jedną poprawną składniowo funkcję zmieniającą w bloku prawym wartość atrybutu .src dużego zdjęcia (prawidłowa definicja funkcji i operacja getElementBy…)

    ok. 3 min
    Polecenie z arkusza

    Aktywne zdjęcie początkowo jest zdjęciem pierwszym. Wciśnięcie przycisku „next” zmienia aktywne zdjęcie na następne.

    • function showNext() - funkcja wyświetlająca następne zdjęcie,
    • activePhoto++ - numer aktywnego zdjęcia rośnie o 1,
    • document.getElementById("photo") - duże zdjęcie po identyfikatorze, metoda z tabeli 1 arkusza,
    • .src = activePhoto + ".jpg" - zmiana atrybutu (element.attribute_name z tabeli 1): liczba sklejona z napisem daje nazwę pliku, np. 2.jpg.

    Przycisk „next” dostaje atrybut onclick="showNext()" (R.3.3). Sprawdzone w Chrome: kolejne kliknięcia pokazują 2.jpg, 3.jpg, 4.jpg i 5.jpg (R.5.2). Szóste kliknięcie szuka pliku 6.jpg, którego nie ma - to naprawia następny krok.

    Typowe błędy

    document.getElementById("photo").innerHTML = … nie zmienia obrazu - <img> nie ma zawartości, plik wskazuje wyłącznie atrybut src.

    galeria.html HTML zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button>prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
            <button onclick="showNext()">next</button>
            <hr>
            <img src="1.jpg" alt="miniatura" class="thumb">
            <img src="2.jpg" alt="miniatura" class="thumb">
            <img src="3.jpg" alt="miniatura" class="thumb">
            <img src="4.jpg" alt="miniatura" class="thumb">
            <img src="5.jpg" alt="miniatura" class="thumb">
        </section>
        <footer>
            <a href="https://pixabay.com" target="_blank">Więcej obrazów</a>
            <p>Galerię wykonał: Bartosz Bryniarski</p>
        </footer>
        <script>
            let activePhoto = 1;
    
            function showNext() {
                activePhoto++;
                document.getElementById("photo").src = activePhoto + ".jpg";
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  42. Krok 42: Funkcja „next”: po piątym zdjęciu pierwsze

    Kryteria:

    R.5.5 Po kliknięciu przycisku next duże zdjęcie jest zmieniane na następne lub w przypadku piątego - na pierwsze

    ok. 2 min
    Polecenie z arkusza

    Ponieważ zdjęć jest 5, gdy aktywnym zdjęciem jest piąte, po wciśnięciu „next” aktywnym zdjęciem zostaje pierwsze.

    Instrukcja warunkowa if: gdy aktywne jest piąte zdjęcie (== - dwa znaki równości to porównanie), numer wraca do 1, a w każdym innym przypadku (else) rośnie o 1. Sprawdzone w Chrome: pięć kliknięć „next” od pierwszego zdjęcia daje 2, 3, 4, 5 i znów 1 (R.5.5).

    Typowe błędy

    activePhoto++ przed if i warunek activePhoto > 5 też działa, ale if (activePhoto = 5) z jednym znakiem równości przypisuje 5 - każde kliknięcie pokazuje wtedy pierwsze zdjęcie.

    galeria.html HTML zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button>prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
            <button onclick="showNext()">next</button>
            <hr>
            <img src="1.jpg" alt="miniatura" class="thumb">
            <img src="2.jpg" alt="miniatura" class="thumb">
            <img src="3.jpg" alt="miniatura" class="thumb">
            <img src="4.jpg" alt="miniatura" class="thumb">
            <img src="5.jpg" alt="miniatura" class="thumb">
        </section>
        <footer>
            <a href="https://pixabay.com" target="_blank">Więcej obrazów</a>
            <p>Galerię wykonał: Bartosz Bryniarski</p>
        </footer>
        <script>
            let activePhoto = 1;
    
            function showNext() {
                if (activePhoto == 5) {
                    activePhoto = 1;
                } else {
                    activePhoto++;
                }
                document.getElementById("photo").src = activePhoto + ".jpg";
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  43. Krok 43: Funkcja „prev”: poprzednie zdjęcie, po pierwszym piąte

    Kryteria:

    R.5.4 Po kliknięciu przycisku prev duże zdjęcie jest zmieniane na poprzednie lub w przypadku pierwszego - na piąte

    ok. 2 min
    Polecenie z arkusza

    Podobnie wciskając przycisk „prev”, aktywne zdjęcie jest zmieniane na poprzednie, np. 4 -> 3, 3 -> 2 ale 1 -> 5.

    Druga funkcja jest lustrzanym odbiciem pierwszej: przy pierwszym zdjęciu numer przeskakuje na 5, w pozostałych przypadkach maleje o 1 (activePhoto--). Przycisk „prev” dostaje onclick="showPrevious()".

    Sprawdzone w Chrome: z piątego zdjęcia dwa kliknięcia „prev” dają 4 i 3, a z pierwszego - od razu 5 (R.5.4).

    galeria.html HTML zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button onclick="showPrevious()">prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
            <button onclick="showNext()">next</button>
            <hr>
            <img src="1.jpg" alt="miniatura" class="thumb">
            <img src="2.jpg" alt="miniatura" class="thumb">
            <img src="3.jpg" alt="miniatura" class="thumb">
            <img src="4.jpg" alt="miniatura" class="thumb">
            <img src="5.jpg" alt="miniatura" class="thumb">
        </section>
        <footer>
            <a href="https://pixabay.com" target="_blank">Więcej obrazów</a>
            <p>Galerię wykonał: Bartosz Bryniarski</p>
        </footer>
        <script>
            let activePhoto = 1;
    
            function showNext() {
                if (activePhoto == 5) {
                    activePhoto = 1;
                } else {
                    activePhoto++;
                }
                document.getElementById("photo").src = activePhoto + ".jpg";
            }
    
            function showPrevious() {
                if (activePhoto == 1) {
                    activePhoto = 5;
                } else {
                    activePhoto--;
                }
                document.getElementById("photo").src = activePhoto + ".jpg";
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  44. Krok 44: Funkcja miniatury: kliknięte zdjęcie staje się aktywne

    Kryteria: ,

    R.3.4 Dla dowolnej miniatury zdefiniowano obsługę zdarzenia kliknięcia (atrybut onClick lub słuchacz zdarzenia click, lub właściwość onclick obiektu DOM)

    R.5.6 Po kliknięciu miniatury duże zdjęcie jest zmieniane na zdjęcie odpowiadające miniaturze (przetestować na zmianę z przyciskami)

    ok. 3 min
    Polecenie z arkusza

    Po kliknięciu na miniaturę, aktywnym zdjęciem staje się to kliknięte.

    Trzecia funkcja dostaje numer zdjęcia w parametrze number i zapisuje go w zmiennej activePhoto - kliknięta miniatura staje się aktywnym zdjęciem, a nie tylko podmienia obraz. Każda miniatura wywołuje ją ze swoim numerem: onclick="showPhoto(1)" przy 1.jpg, showPhoto(2) przy 2.jpg i tak dalej (R.3.4).

    Sprawdzone w Chrome: kliknięcie czwartej miniatury pokazuje 4.jpg (R.5.6). Skrypt ma teraz zmienną i trzy funkcje - dokładnie tyle, ile wymaga arkusz.

    Typowe błędy

    Funkcja, która zmienia tylko src (np. document.getElementById("photo").src = "4.jpg"), a nie zmienną, psuje przyciski: po kliknięciu miniatury 4 przycisk „next” pokaże zdjęcie następne po poprzednio aktywnym, a nie 5.

    galeria.html HTML zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button onclick="showPrevious()">prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
            <button onclick="showNext()">next</button>
            <hr>
            <img src="1.jpg" alt="miniatura" class="thumb" onclick="showPhoto(1)">
            <img src="2.jpg" alt="miniatura" class="thumb" onclick="showPhoto(2)">
            <img src="3.jpg" alt="miniatura" class="thumb" onclick="showPhoto(3)">
            <img src="4.jpg" alt="miniatura" class="thumb" onclick="showPhoto(4)">
            <img src="5.jpg" alt="miniatura" class="thumb" onclick="showPhoto(5)">
        </section>
        <footer>
            <a href="https://pixabay.com" target="_blank">Więcej obrazów</a>
            <p>Galerię wykonał: Bartosz Bryniarski</p>
        </footer>
        <script>
            let activePhoto = 1;
    
            function showNext() {
                if (activePhoto == 5) {
                    activePhoto = 1;
                } else {
                    activePhoto++;
                }
                document.getElementById("photo").src = activePhoto + ".jpg";
            }
    
            function showPrevious() {
                if (activePhoto == 1) {
                    activePhoto = 5;
                } else {
                    activePhoto--;
                }
                document.getElementById("photo").src = activePhoto + ".jpg";
            }
    
            function showPhoto(number) {
                activePhoto = number;
                document.getElementById("photo").src = activePhoto + ".jpg";
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  45. Krok 45: Nawigacja na zmianę miniaturami i przyciskami

    Kryteria:

    R.5.3 Funkcje skryptu są kontrolowane przez zmienną przechowującą numer zdjęcia. Zmienna jest modyfikowana zgodnie z kontekstem aplikacji, wg wzoru: 1. przycisk next -> gdy zdjęcie 5 -> 1 lub inkrementacja 2. przycisk prev -> gdy zdjęcie 1 -> 5 lub dekrementacja 3. miniatura -> zmienna przyjmuje wartość numeru zdjęcia np. zmienna = parseInt(nazwa);

    ok. 2 min
    Polecenie z arkusza

    Aplikacja utrzymuje kontekst tak, że użytkownik może nawigować na zmianę miniaturami oraz przyciskami.

    „Kontekst” to numer aktywnego zdjęcia w zmiennej activePhoto. Każda z trzech funkcji czyta go albo zmienia według tego samego wzoru, co w kluczu: „next” - z 5 na 1 albo o jeden w górę, „prev” - z 1 na 5 albo o jeden w dół, miniatura - zmienna przyjmuje numer zdjęcia (R.5.3). Kod się nie zmienia; to sprawdzenie całości.

    Sprawdzone w Chrome, na zmianę: miniatura 4 → 4.jpg, „next” → 5.jpg, „next” → 1.jpg, „prev” → 5.jpg, miniatura 1 → 1.jpg, „prev” → 5.jpg. Przyciski zawsze ruszają od zdjęcia wybranego ostatnio, także miniaturą.

    Podgląd strony bez zmian - taki jak po kroku 44.

  46. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 46-47 · po tym etapie masz 38 z 38 kryteriów (pkt)

    Krok 46: Zabezpieczenie: odnośnik do obcej strony w nowej karcie

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku stopki: odnośnik do strony https://pixabay.com otwierany w nowej karcie przeglądarki i podpisany „Więcej obrazów”

    Strona otwarta przez target="_blank" dostawała dawniej odwołanie do karty, z której ją otwarto (window.opener), i mogła po cichu podmienić jej adres, np. na fałszywą kopię galerii z formularzem logowania - użytkownik wraca do pierwszej karty i nie zauważa zmiany. rel="noopener" odcina to odwołanie, a noreferrer dodatkowo nie przekazuje obcej stronie adresu, z którego przyszedł użytkownik. Nowe przeglądarki dodają noopener do target="_blank" same, ale atrybut zapisany jawnie działa także w starszych. Na egzaminie nie jest wymagany.

    galeria.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Galeria obrazów</h1>
        </header>
        <section id="left">
            <img src="zdjecie.jpg" alt="zdjęcie dnia">
            <h3>Zdjęcia opublikowali</h3>
            <table>
                <tr>
                    <td>Anna Porada</td>
                    <td>10 zdjęć</td>
                </tr>
                <tr>
                    <td>Krzysztof Wasilewski</td>
                    <td>12 zdjęć</td>
                </tr>
                <tr>
                    <td>Monika Kowalska</td>
                    <td>4 zdjęcia</td>
                </tr>
            </table>
        </section>
        <section id="right">
            <button onclick="showPrevious()">prev</button>
            <img src="1.jpg" alt="galeria" id="photo">
            <button onclick="showNext()">next</button>
            <hr>
            <img src="1.jpg" alt="miniatura" class="thumb" onclick="showPhoto(1)">
            <img src="2.jpg" alt="miniatura" class="thumb" onclick="showPhoto(2)">
            <img src="3.jpg" alt="miniatura" class="thumb" onclick="showPhoto(3)">
            <img src="4.jpg" alt="miniatura" class="thumb" onclick="showPhoto(4)">
            <img src="5.jpg" alt="miniatura" class="thumb" onclick="showPhoto(5)">
        </section>
        <footer>
            <a href="https://pixabay.com" target="_blank" rel="noopener noreferrer">Więcej obrazów</a>
            <p>Galerię wykonał: Bartosz Bryniarski</p>
        </footer>
        <script>
            let activePhoto = 1;
    
            function showNext() {
                if (activePhoto == 5) {
                    activePhoto = 1;
                } else {
                    activePhoto++;
                }
                document.getElementById("photo").src = activePhoto + ".jpg";
            }
    
            function showPrevious() {
                if (activePhoto == 1) {
                    activePhoto = 5;
                } else {
                    activePhoto--;
                }
                document.getElementById("photo").src = activePhoto + ".jpg";
            }
    
            function showPhoto(number) {
                activePhoto = number;
                document.getElementById("photo").src = activePhoto + ".jpg";
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.html)
  47. Krok 47: Zabezpieczenie: konto leon i jego hasło

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: Nadające użytkownikowi leon@localhost jedynie wszystkie prawa do manipulowania danymi we wszystkich tabelach bazy gory

    Konto z arkusza jest dobrym przykładem zasady najmniejszych uprawnień: aplikacja, która tylko czyta i zmienia rekordy, łączy się z bazą kontem bez prawa do zmiany budowy bazy. Sprawdzone logowaniem na konto leon: dodanie, zmiana i usunięcie rekordu działają, a DROP TABLE szczyty i CREATE USER kończą się odmową dostępu. Gdyby ktoś przejął stronę korzystającą z tego konta (np. przez wstrzyknięcie SQL), zmieni dane, ale nie skasuje tabeli ani nie założy sobie nowego konta. Konto root bez hasła z XAMPP-a nadaje się wyłącznie do ćwiczeń na własnym komputerze.

    Hasło Leon%Zawodowiec musi stać jawnie w kwerendy.txt, bo tego wymaga arkusz. Poza egzaminem zapytania z hasłami nie trafiają do plików, które się komuś przekazuje ani do repozytorium kodu - hasło wpisuje się bezpośrednio w phpMyAdmin albo trzyma w pliku konfiguracyjnym poza folderem strony. Do prawdziwych kont służy długie, losowe hasło, a zmienia się je poleceniem ALTER USER 'leon'@'localhost' IDENTIFIED BY '…';.

    Podgląd strony bez zmian - taki jak po kroku 46.

  48. Etap 6: Oddanie pracy

    Krok 48 · po tym etapie masz 38 z 38 kryteriów (pkt)

    Krok 48: Plik przeglądarka.txt i nagranie płyty

    ok. 5 min
    Polecenie z arkusza

    UWAGA: po zakończeniu pracy utwórz w folderze z numerem, którym został podpisany arkusz 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. W folderze powinny się znajdować pliki z grafiką 1.jpg ÷ 5.jpg oraz pliki: galeria.html, grants.png, import.jpg, kw1.png, kw2.png, kw3.png, kw4.png, kwerendy.txt, przeglądarka.txt, styl2.css, zdjecie.jpg ewentualnie inne przygotowane pliki. Po nagraniu płyty sprawdź poprawność nagrania. Opisz płytę numerem, którym został podpisany arkusz i pozostaw na stanowisku, zapakowaną w pudełku wraz z arkuszem egzaminacyjnym.

    W przeglądarka.txt wpisujesz nazwę przeglądarki, w której sprawdzasz stronę.

    Lista plików z arkusza to jednocześnie lista kontrolna: zdjęcia 1.jpg - 5.jpg, wykadrowany zdjecie.jpg, galeria.html, styl2.css, cztery zrzuty zapytań, import.jpg, grants.png, kwerendy.txt i przeglądarka.txt. Plik szczyty.sql może zostać. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem zdającego. Pusta lub nieczytelna płyta to zero punktów za wszystkie pięć rezultatów.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

    Podgląd strony bez zmian - taki jak po kroku 46.

Podgląd

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: . 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.

Potwierdzenie

Informacja