Jaki będzie efekt wykonania przedstawionych instrukcji JavaScript?
| var elementy = document.getElementsByClassName("styl1"); for(var i = 0; i < elementy.length; i++) elementy[i].style.fontWeight = "bolder"; |
A. Tylko dla elementu o id równym styl1 zostanie przypisany styl pogrubienia tekstu na bolder.
B. Dla wszystkich elementów przypisanych do klasy styl1 zostanie nadany styl pogrubienia tekstu bolder.
C. Tylko dla pierwszego elementu przypisanego do klasy styl1 zostanie nadany styl pogrubienia tekstu bolder.
D. Dla wszystkich elementów na stronie zostanie przypisany styl pogrubienia tekstu na bolder.
Pytanie z egzaminu CKE, czerwiec 2022 (arkusz EE.09-SG-22.06).
Instrukcje pobierają z dokumentu wszystkie elementy, które mają przypisaną klasę CSS styl1, a potem w pętli ustawiają im właściwość style.fontWeight na wartość bolder. Kluczowe jest tutaj użycie metody document.getElementsByClassName('styl1'). Ona nie szuka identyfikatora id, tylko klasy, i zwraca kolekcję elementów, czyli HTMLCollection. Następnie pętla for przechodzi od indeksu 0 do elementy.length - 1, więc obejmuje każdy element znajdujący się w tej kolekcji. W praktyce oznacza to, że jeżeli na stronie są na przykład akapit, nagłówek i komórka tabeli z class='styl1', to wszystkie te elementy dostaną pogrubienie bolder. Moim zdaniem to jeden z podstawowych przykładów manipulacji DOM, który dobrze pokazuje różnicę między CSS zapisanym w arkuszu stylów a stylem ustawianym dynamicznie przez JavaScript. W dobrych praktykach często zamiast bezpośrednio zmieniać style inline lepiej dodaje się klasę, np. przez classList.add(), bo łatwiej wtedy utrzymać kod CSS. Ale sama logika z pętlą jest poprawna i często używana przy masowej zmianie elementów strony.
W tym kodzie łatwo pomylić kilka pojęć z DOM, szczególnie jeśli ktoś kojarzy selektory CSS tylko ogólnie. Metoda getElementsByClassName nie wybiera wszystkich elementów na stronie, tylko te, które mają konkretną klasę. Gdyby celem było przejście po wszystkich elementach dokumentu, trzeba by użyć czegoś w rodzaju document.getElementsByTagName('*') albo odpowiedniego selektora w querySelectorAll. Sama obecność pętli for nie oznacza jeszcze, że obejmowana jest cała strona; pętla działa tylko na kolekcji zwróconej wcześniej przez metodę wyszukującą.
Nie chodzi też o element z id równym styl1. W JavaScript do pobierania elementu po identyfikatorze używa się zwykle document.getElementById('styl1'), a id zgodnie z dobrymi praktykami powinno być unikalne w dokumencie HTML. Klasa działa inaczej: może być przypisana do wielu elementów, więc metoda zwraca wiele wyników. To jest częsty błąd myślowy, bo zapis styl1 wygląda tak samo jako tekst, ale znaczenie zależy od użytej metody albo selektora.
Kod nie ogranicza się również do pierwszego elementu z klasą styl1. Gdyby programista chciał zmienić tylko pierwszy pasujący element, mógłby odwołać się bezpośrednio do elementy[0] albo użyć document.querySelector('.styl1'). Tutaj jednak pętla sprawdza i < elementy.length i za każdym obrotem zwiększa i, więc dochodzi po kolei do wszystkich elementów w kolekcji. Z mojego doświadczenia właśnie takie detale w pętlach są ważne, bo jedna linijka decyduje, czy zmieniasz pojedynczy komponent, czy całą grupę elementów interfejsu.
Nie chodzi też o element z id równym styl1. W JavaScript do pobierania elementu po identyfikatorze używa się zwykle document.getElementById('styl1'), a id zgodnie z dobrymi praktykami powinno być unikalne w dokumencie HTML. Klasa działa inaczej: może być przypisana do wielu elementów, więc metoda zwraca wiele wyników. To jest częsty błąd myślowy, bo zapis styl1 wygląda tak samo jako tekst, ale znaczenie zależy od użytej metody albo selektora.
Kod nie ogranicza się również do pierwszego elementu z klasą styl1. Gdyby programista chciał zmienić tylko pierwszy pasujący element, mógłby odwołać się bezpośrednio do elementy[0] albo użyć document.querySelector('.styl1'). Tutaj jednak pętla sprawdza i < elementy.length i za każdym obrotem zwiększa i, więc dochodzi po kolei do wszystkich elementów w kolekcji. Z mojego doświadczenia właśnie takie detale w pętlach są ważne, bo jedna linijka decyduje, czy zmieniasz pojedynczy komponent, czy całą grupę elementów interfejsu.