od Podstaw
9 godz. 20 min · JavaScript · Full-stack i Programowanie
Piotr PalarzWeb DeveloperJavaScript to język programowania, który napędza niemal wszystkie strony internetowe. Dopełnia on technologie HTML i CSS, za pomocą których tworzymy strukturę i wygląd dokumentu. Co jednak w sytuacji, gdy chcemy po kliknięciu w wybrany przycisk wyświetlić powiększone zdjęcie lub wczytać dodatkowe dane z serwera? To właśnie w takich sytuacjach przydaje się język JavaScript i tzw. DOM API, dostępne w przeglądarce. Jak się przekonasz, możliwości nowoczesnych przeglądarek w połączeniu z tym językiem są naprawdę ogromne.
Język JavaScript może być używany nie tylko na stronach internetowych. Z tego powodu, w kursie omówimy najpierw najważniejsze konstrukcje tego języka, które są niezależne od platformy uruchomieniowej. Dzięki temu zbudujesz fundamenty niezbędne do tego, by wykorzystać ten język np. w środowisku Node.js. Krok po kroku omówimy sposoby tworzenia zmiennych, dostępne typy danych i operatory. Następnie zobaczysz jak tworzyć tablice i obiekty, z jakich instrukcji warunkowych i pętli możesz korzystać, a także jak tworzyć własne funkcje. Przekazywana wiedza uwzględniać będzie nowości, które pojawiły się w języku wraz z rewolucyjnym standardem EcmaScript 6 (ES6).
Sam język JavaScript to nie wszystko, by tchnąć ducha w strony internetowe. Z tego powodu, przeglądarki internetowe udostępniają tzw. DOM API. To interfejs, który z użyciem języka JavaScript pozwala na manipulację treścią i wyglądem strony. W kursie bardzo dokładnie omówimy czym jest Obiektowy Model Dokumentu, a także jak z nim pracować. Zobaczysz jak tworzyć nowe elementy HTML i wstawiać je na stronę, jak modyfikować ich treść, atrybuty, style czy klasy CSS. Poznasz sposoby na odczytywanie położenia elementu na stronie i jego wymiarów, które będą niezbędne w wielu sytuacjach. Dowiesz się także, jak przypisywać obsługę zdarzeń w przeglądarce, by np. wywołać własną funkcję, gdy ktoś kliknie w wybrany przez Ciebie przycisk.
JSON to popularny format wymiany danych, a Ajax to potoczna nazwa dla asynchronicznych zapytań HTTP, które wysyłać możemy z poziomu kodu JavaScript. Dziś niemal każda strona internetowa wykorzystuje te technologie. W niektórych przypadkach jako dopełnienie podstawowej funkcjonalności witryny, a w innych jako główny motor napędzający stronę. Jeśli kiedykolwiek widziałeś, jak na stronie internetowej jakaś treść "doczytuje" się np. podczas przewijania - widziałeś w praktyce Ajax. W jednym z rozdziałów kursu zobaczysz, jak pracować z tym formatem, a także jak wysyłać wspomniane zapytania do serwera.
Choć kurs który masz przed sobą, jest kursem dla początkujących, to aby zrozumieć jak działa język JavaScript i jak z nim się współcześnie pracuje, omówimy dwa ważne tematy - zarządzanie zależnościami i bundlowanie kodu. Dowiesz się czym jest npm i jak z jego pomocą pobierać paczki gotowego kodu z internetu, a także jak sprawić, by bez trudnu dołączać je do własnego kodu. W tym celu skorzystamy z narzędzia snowpack, które pozwoli nam także na optymalizację kodu przed jego wypuszczeniem w świat. Na tym etapie omówimy również jak działają moduły ESM, pozwalające dzielić kod na mniejsze części.
Kurs podzielony został na możliwie krótkie lekcje, do których w każdej chwili możesz wrócić. Jeśli zatem zapomnisz jak odczytywać wymiary elementu na stronie, szybko odnajdziesz odpowiednią lekcję. Czym jednak była by sama teoria i proste przykłady, bez pokazania, jak połączyć je w całość i wykorzystać w praktyce? Dobra wiadomość jest taka, że w kursie stworzymy aż 5 praktycznych projektów, wykorzystujących zdobytą wcześniej wiedzę. Najpierw napiszemy program losujący Dużego Lotka, następnie dynamiczny pasek postępu przeczytania artykułu, dymek pojawiający się nad elementem po najechaniu na niego myszą, wygenerujemy tabelkę w użytkownikami na podstawie danych JSON, a na koniec tworzymy prosty odtwarzacz wideo, z możliwością pauzowania i przewijania filmu.
Kurs ten jest dla wszystkich osób, które znają już podstawy HTML i CSS i chciałyby przejść poziom wyżej i dodać do swoich stron dynamiczności. Żadna wcześniejsza wiedza z zakresu JavaScript nie jest wymagana, ale zalecana jest podstawowa wiedza z zakresu samego programowania (czym są zmienne, pętle, funkcje itd.). Materiał ten będzie również świetnym odświeżeniem i usystematyzowaniem wiedzy dla osób, które już z tym językiem miały do czynienia. Po przerobieniu tego kursu będziesz gotowy, by poznawać język JavaScript dalej i zacząć korzystać z nowoczesnych frameworków.
Zdarzeń, które wywołuje przeglądarka jest bardzo wiele i część z nich to mogą być
takie na akcje użytkownika właśnie jak kliknięcie w jakiś przycisk, a część są to
takie zdarzenia można powiedzieć UI, czyli np.
jak strona się wczyta to jest wywoływane zdarzenie load, a kiedy wczyta się drzewo
DOM jest wywoływane zdarzenie DOMContentLoaded i o tych dwóch powiemy sobie teraz.
Teraz o co chodzi?
Zobacz, mamy tutaj jakiś obrazek na stronie, który się wczytuje z zewnętrznego
serwera i mamy tutaj skrypt podłączony poniżej.
Więc na etapie tego skryptu możemy się
odwołać do tego obrazka i chciałbym odczytać jego szerokość.
Więc pobrałem sobie go tutaj do stałej i
zrobimy sobie console.log i w takim Template Stringu
wymiary obrazka to
i tutaj sobie zinterpolujemy img.offsetWidth i dodamy sobie piksele
albo zrobimy tutaj taki x i następnie zrobimy img.offsetHeight
i tutaj dopiszemy px.
Czyli po prostu jak się wczyta ten skrypt chcę wyświetlić wymiary obrazka.
No i zobaczmy.
Jak widzisz tutaj to wszystko działa poprawnie.
Przejdźmy sobie jeszcze do panelu Network.
Zaznaczymy Disable cache,
to oznacza, że za każdym odświeżeniem
chcemy od nowa pobierać wszystkie zasoby na stronie.
I zauważ wydaje się, że tutaj wszystko jest ok.
Czyli trudno jest mi pokazać, że występuje tutaj pewien problem,
dlatego przejdźmy może do panelu Network i przejdziemy sobie tutaj do tego online i
wybierzemy Slow 3G, czyli chcemy spowolnić nasze połączenie.
Zobaczmy, teraz jak się strona odświeży,
ten obrazek będzie dłużej pobierany
i zauważ co tutaj się wydarzyło.
Wymiary obrazka to 0 na 0.
Jaki tutaj jest problem?
Otóż ta strona kiedy się wczytuje przeglądarka dochodzi do tego obrazka
to ona nie blokuje wczytywania dalszej
strony tylko asynchronicznie pobiera ten obrazek, więc leci niżej,
dochodzi do skryptu, pobiera nasz skrypt on się pobrał szybko, wykonuje ten skrypt,
ten skrypt na stronie znajduje obrazek, bo
on rzeczywiście tutaj jest jako element, ale jeszcze nie ma pobranego obrazka,
który jest tam podstawiony. I nasz skrypt próbuje odczytać sobie wielkość tego obrazka
i otrzymuje 0 dlatego, że ta strona jeszcze całkowicie się nie wczytała.
I teraz w jaki sposób możemy sobie z tym poradzić?
Otóż możemy przypisać zdarzenie do obiektu window.
Jest taki obiekt window i też można na nim wykonać addEventListener
i jest zdarzenie, które nazywa się load.
Przekażemy funkcję i powiemy, że chcemy wywołać tę funkcję dopiero wtedy, kiedy
cała strona się wczyta, a więc wszystkie obrazki itd.
W środku możemy się odwołać do tego img,
albo mogłoby to być na zewnątrz, to akurat nie ma znaczenia w tym przypadku.
I tutaj dopiero chcemy wyświetlić wymiary tego obrazka.
Zapiszmy.
I znowu mamy tutaj ustawione to spowolnienie,
odświeża się ta strona
i będziemy czekać aż ona się wczyta,
ale w momencie dopiero jak się wczyta to wywoła się nasza funkcja, która pobierze
wymiary tego obrazka i powinniśmy wtedy dopiero zobaczyć ten wynik w konsoli.
Jak widzimy strona jeszcze się wczytuje,
jeszcze się nie wczytała, chociaż obrazek już widzimy.
A więc to zdarzenie load wykona się
dopiero wtedy, kiedy wczyta się absolutnie wszystko.
No i teraz wymiary obrazka są poprawne.
To może być bardzo przydatne jakbyś tworzył jakiś slider czy inne rzeczy,
gdzie naprawdę bazujesz na wymiarach danego elementu na stronie.
To było zatem zdarzenie load na obiekcie
window, ale mamy jeszcze jedno zdarzenie, które jest bardzo istotne.
Zróbmy sobie coś takiego, że wyszuka na stronie h1 document.querySelector h1.
Mamy tam taki element i będę chciał
odczytać jego tekstContent, czyli po prostu to co znajduje się w tej h1.
Co to będzie ten tekst.
Wyłączymy sobie to spowalnianie, żeby nam się strona szybko wczytywała, więc ze slow
zmienimy na online po prostu i wrócę do konsoli ok?
No i jak widzimy zdarzenie DOMContentLoaded i load czyli wszystko jest ok.
Ale ja już Ci w tym kursie mówiłem, że te skrypty podłączaliśmy cały czas na dole,
a mogą się zdarzyć takie sytuacje i czasami tak jest na stronach, że skrypt
jest podłączany u góry tutaj w elemencie head.
Nie do końca jest to dobra praktyka,
dlatego, że ta cała strona jest biała do momentu aż cały ten skrypt się wczyta, bo
przeglądarka blokuje renderowanie strony jak napotka jakiś skrypt.
Natomiast co by się stało w sytuacji jeżeli ten skrypt byłby w head?
Zobacz, że on jest teraz tutaj i w tym
skrypcie próbujemy się odwołać do h1, pobrać jej tekst content.
Otóż otrzymamy błąd, że chcemy odczytać właściwość textContent na null.
Dlaczego tak się dzieje?
Bo document.querySelektor zwróciło nam
null i my na null, który nie jest obiektem
zrobiliśmy kropka textContent.
I na tym etapie, kiedy ten skrypt się
wczytuje, nie mamy dostępu do tego h1, ale możemy przypisać zdarzenie DOMContentLoaded
tym razem do elementu document czy do tego obiektu addEventListener
i tutaj bardzo ważne jest, żeby to wpisać
odpowiednio, czyli tutaj wielkie litery, potem tak DOMContentLoaded,
chcemy wywołać funkcję
i w tej funkcji znajdziemy h1 i wyświetlimy jej textContent.
Zobacz jaki teraz będzie efekt.
Nie ma błędu i wszystko działa poprawnie.
Czyli innymi słowy to zdarzenie DOMContentLoaded wywoła się dopiero wtedy,
ta funkcja się wtedy wywoła, kiedy przeglądarka sparsuje cały dokument. I wtedy
mamy pewność, że wszystkie elementy na stronie są utworzone, natomiast nie muszą
być pobrane wszystkie obrazki, więc to nie jest to samo co window.load.
Tutaj chodzi tylko o to, że wszystkie
elementy HTML są utworzone, mamy do nich dostęp,
ale gdybyśmy tutaj spróbowali odczytać wielkość tego obrazka, też byśmy otrzymali
0 na 0, bo on jeszcze nie został w całości pobrany.
Na koniec pokażę Ci jeszcze atrybut, który
zadziała tak samo jak to zdarzenie DOMContentLoaded
czyli jeżeli to stąd wyciągnę i wykomentuję, dodamy sobie to tutaj zobaczymy błąd,
ale możemy dodawać do skryptu w momencie kiedy go podpinamy
taki atrybut, który nazywa się defer i
on działa dokładnie tak jak DOMContentLoaded.
Czyli to oznacza, że ten skrypt możesz pobrać,
mówimy przeglądarce, ale wykonaj go
dopiero wtedy, kiedy całe drzewo DOM będzie sparsowane.
Więc teraz jeżeli odświeżę,
jak widzisz efekt jest dokładnie taki sam. Czyli z tej lekcji
zapamiętaj sobie, że jeżeli chcesz mieć pewność, że pobierane przez Ciebie
elementy te wyszukiwane na stronie, na stronie na pewno się znajdują, to wywołaj
sobie swój kod w funkcji obsługi DOMContentLoaded i wtedy nie ma znaczenia
czy będziesz podpinał ten skrypt w head czy będzie podpinany na dole
na pewno wszystko będzie ok.
A jeżeli polegasz na jakichś wymiarach lub po prostu chcesz wykonać jakiś kod, kiedy
cała strona już się wczytała, to przypisz do window zdarzenie load.