od Podstaw
10 godz. 55 min · JavaScript · Full-stack i Programowanie
Piotr PalarzWeb DeveloperJeśli poznałeś już wymienione wyżej technologie, to zapewne zdajesz sobie sprawę z ich ograniczeń. Za pomocą języka HTML tworzymy bowiem strukturę dokumentu, dodajemy treść tekstową, obrazy czy wideo. Aby jednak strona internetowa wyglądała perfekcyjnie, korzystamy z arkuszy stylów CSS, które pozwalają nam opisać wygląd wszystkich elementów HTML, ustawić wielkość tekstu czy dodać tło strony. No właśnie, ale gdzie tutaj interakcyjność?Zapewne już wiesz, że język CSS oferuje tzw. pseudoklasy, które pozwalają nam np. przypisać zmianę koloru elementu po najechaniu na niego kursorem myszy. I to tak naprawdę wszystko, na co możemy zareagować. A co gdybyśmy chcieli po wciśnięciu jakiegoś przycisku wysunąć ukryty panel, sprawdzić poprawność wypełnianego właśnie formularza lub pobrać dane z serwera i wyświetlić je na stronie bez przeładowywania witryny? Dobra wiadomość jest taka, że to wszystko jest możliwe z użyciem języka JavaScript, który “rozumie” każda przeglądarka internetowa.Choć język JavaScript powstał jako język skryptowy na potrzeby stron internetowych, to już dawno temu “wyszedł” z przeglądarek internetowych i może być używany tak naprawdę gdziekolwiek. W kursie, który masz przed sobą, poznasz język JavaScript jako niezależny język programowania, a dopiero później dowiesz się, jak wykorzystywać go do wzbogacania stron internetowych. Dzięki postawieniu grubej linii pomiędzy samym językiem, a Obiektowym Modelem Dokumentu dostępnym w przeglądarkach internetowych, będziesz nie tylko bardzo dobrze rozumiał sam język, ale w przyszłości wykorzystasz go do innych zastosowań.Na początku omówimy ciekawą historię języka JavaScript, a chwilę później rozpoczniemy poznawanie najważniejszych jego konstrukcji. I tak dowiesz się czym są zmienne, jakie typy danych dostępne są w tym języku, czym są liczne operatory, instrukcje warunkowe, pętle, tablice, obiekty i funkcje. Wszystkie te zagadnienia są bardzo podobne w innych językach programowania, dlatego kurs ten jest również świetnym wstępem do programowania w ogóle. Każda z przedstawianych konstrukcji języka jest bardzo dokładnie tłumaczona z myślą osobach początkujących. Nie zmienia to jednak faktu, że nawet osoby znające już podstawy języka JavaScript znajdą tutaj coś dla siebie, gdyż na każdym etapie przedstawiane są również liczne ciekawostki odnośnie danej konstrukcji.Kiedy zrozumiesz już jak działa język JavaScript, przejdziemy do drugiej połowy kursu, gdzie dokładnie omówimy Obiektowy Model Dokumentu, dostępny w przeglądarkach internetowych. Zobaczysz jak przeglądarka tworzy z kodu HTML drzewo dokumentu, jak reprezentowane są poszczególne jego węzły, a także jak język JavaScript potrafi z tym “wewnętrznym światem” współpracować. Dowiesz się jak wyszukiwać na stronie interesujących nas elementów HTML, a także jak tworzyć nowe elementy, przypisywać im treść i wstawiać je na stronę. Popracujemy również z atrybutami elementów, ich klasami i wreszcie ze stylami CSS, abyśmy mogli wpływać dynamicznie na wygląd naszej strony.Zobaczysz również, jak możemy w dowolnym momencie odczytać współrzędne położenia elementu na stronie, a także jego wysokość czy szerokość. Tę wiedzę wykorzystamy później w praktycznym przykładzie.Jeden z rozdziałów kursu poświęcony został zdarzeniom, a więc możliwości reagowania na zachowania użytkownika. Dzięki temu zobaczysz, jak możemy przypisać np. zdarzenie kliknięcia do wybranego elementu, a kiedy zostanie on kliknięty, wykona się przygotowany przez nas kod. Poznasz kilka różnych sposobów na przypisywanie oraz usuwanie zdarzeń, a także dowiesz się czym jest tzw. “bubbling” oraz “capturing” czy jak zablokować domyślną akcję przeglądarki.Przy pisaniu jakiegokolwiek kodu, zawsze pojawiają się błędy, dlatego i tutaj Twoje wątpliwości nie pozostaną bez odpowiedzi. Poznasz wszystkie typu błędów, które mogą się pojawić podczas wykonywania naszego kodu, a także wiele sposobów ich wykrycia i wyeliminowania.W kursie nie brakuje oczywiście praktycznych przykładów, które celowo zostały ułożone tak, aby wykorzystać w nich jak najwięcej zdobytej wcześniej wiedzy. Nie zostaniesz więc sam z poczuciem, że co prawda rozumiesz jak działa dana konstrukcja, ale nie masz pomysłu, kiedy z niej skorzystać. Na początek wykonamy praktyczny projekt losowania liczb z wybranego przedziału tak, aby nie mogły się powtórzyć. Już przy tym projekcie poznasz wiele ciekawych technik i sztuczek.Następnie przejdziemy do nieco bardziej zaawansowanego przykładu i napiszemy skrypt, który pozwoli nam sortować dane w tabeli po wybranych kolumnach, kiedy któraś z nich zostanie kliknięta. Zobaczysz jak sortować dane zarówno malejąco jak i rosnąco, a także jak zmieniać kolejność elementów HTML na stronie.W kolejnym projekcie zajmiemy się walidacją danych wpisywanych do formularza, by ten nie mógł zostać wysłany do serwera tak długo, jak zawiera jakiekolwiek błędy. Zobaczysz tutaj zdarzenia związane z polami formularza, a także sposoby na pobieranie z nich wartości i sprawdzanie czy są one poprawne. Zadbamy także o wrażenia użytkownika i wyświetlimy na stronie stosowne błędy, a także podświetlimy źle uzupełnione pola na czerwono.W przedostatnim projekcie wstawimy na stronę przycisk, który będzie się pojawiał po przewinięciu strony w dół, a znikał po odwrotnej akcji. Co jednak ciekawe, po jego kliknięciu, strona zostanie automatycznie, płynnie przewinięta do samej góry.W ostatnim projekcie stworzymy bardzo efektowny dymek z podpowiedzią, który będzie się pojawiał nad elementem po najechaniu na niego kursorem myszy. Wykorzystamy tutaj mnóstwo ciekawych technik. Dowiesz się również jak swój kod przygotować w taki sposób, abyś mógł go udostępnić innym osobom, by w łatwy sposób skorzystały z przygotowanego Tooltipa na swoich stronach.Kurs kończy się sekcją Tips & Tricks, w której znajdziesz 10 krótkich lekcji. W każdej z nich została omówiona jedna sztuczka. Każda z nich pozwoli Ci jeszcze lepiej zrozumieć język JavaScript, ale przede wszystkim zaoszczędzić czas i kilka linijek często niepotrzebnego kodu.Podsumowując, kurs ten jest nie tylko wprowadzeniem do samego języka JavaScript, ale także do Obiektowego Modelu Dokumentu. Dzięki wyraźnemu rozdzieleniu tych dwóch zagadnień, będziesz mógł w przyszłości wykorzystać język JavaScript także do innych zastosowań, poza przeglądarką internetową.
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 czy programowania nie jest wymagana, gdyż wszystkie konstrukcje są starannie tłumaczone. 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, z kursem JavaScript w Praktyce, który powstał jako dopełnienie tego kursu i porusza nieco bardziej zaawansowane tematy, na które tutaj zabrakło już czasu.
W tej lekcji chciałbym omówić dwie bardzo ważne funkcje, które celowo pominąłem w tej części, w której mówiliśmy
o takim jądrze języka JavaScript, o tym korze języka JavaScript, dlatego że te funkcje nie są oficjalnie
specyfikacji ECMAScript. Natomiast są szeroko dostępne nie tylko w przeglądarce internetowej, ale także
w takich środowiskach uruchomieniowych jak np. Node.js, więc w zasadzie wszędzie możemy z nich korzystać
i teraz pokażę ci jak one działają.
Są to funkcje setTimeout oraz setInterval i zaczniemy od tej pierwszej.
Przejdźmy od razu do kodu i wytłumaczę Ci na czym rzecz polega.
Otóż mamy taką funkcję jak setTimeout. Ona tak wygląda.
Tak naprawdę ona jest dostępna na obiekcie window, więc mogłem tutaj napisać window setTimeout.
Tak jak już wcześniej ci pokazywałem i ta właśnie funkcja przyjmuje tutaj dwa parametry.
Pierwszy z nich jest to funkcja, która ma się wykonać, więc piszę tutaj jakąkolwiek funkcję.
W ten sposób. Napiszemy console.log. Witaj po dwóch sekundach.
Powiem ci zaraz dlaczego.
Co jest tutaj istotne, to oczywiście tak jak w JavaScript'cie już Cię uczyłem, tu nie musisz wpisywać funkcji anonimowej.
Tu możesz podać odwołanie do jakiejkolwiek innej funkcji, czyli jej nazwę lub np. zmienną, która przechowuje
do niej referencje. Natomiast istotne jest bardziej drugi parametr, bo tutaj podajemy w milisekundach,
czas po jakim ma się to funkcja wykonać.
I ja napisałem tutaj Witaj po dwóch sekundach, dlatego tutaj napiszę 2000, 2000 milisekund
to 2 sekundy i setTimeout robi właśnie to, że po dwóch sekundach wykona funkcję, którą tutaj przekazaliśmy.
Przejdźmy do przeglądarki. Odświeżmy.
Poczekamy chwilkę i widzisz console.log, Witaj po dwóch sekundach.
Dokładnie w taki sposób to działa.
Natomiast, co jest ciekawe, ta funkcja coś zwraca za każdym razem, jeżeli funkcja coś zwraca to wiesz, że
możemy to zapisać w zmiennej.
Więc teraz pod spodem, może to wykomentuje albo najpierw skopiuje, później wykomentuje.
Ok.
Stworzymy sobie nową zmienną, nazwę ją timeout i tutaj przypisze to wszystko, czyli wywołanie tej funkcji
setTimeout.
Oprócz tego, że ustawia tą funkcję do wykonania po dwóch sekundach, to jeszcze coś zwraca i to zostanie
zapisane tutaj.
Tym razem chciałbym aby to było 5 sekund, więc tutaj również to zmienimy.
Witaj po pięciu sekundach, bo chcę Ci pokazać, że mam pewną funkcję, która nazywa się clearTiemout, która
pozwala nam taki timeout wyczyścić.
Ona wygląda następująco. I tutaj musimy jej przekazać właśnie timeout, czyli tutaj nie zapisałem go w
zmiennej, więc nie mamy do niego jakby uchwytu, nie wiemy gdzie on jest.
Natomiast, jeżeli tutaj zapisaliśmy go do zmiennej to on właśnie, czyli ta funkcja timeout zwraca tutaj
taką specjalną referencje, którą możemy przekazać do clearTimeout właśnie wpisując ją tutaj.
Natomiast, co ja będę chciał zrobić, wytnę sobie to co tutaj było.
Przejdźmy do przeglądarki. Odświeżę i zobaczysz, że po pięciu sekundach tym razem powinno nam się to wykonać.
Uwaga, jest. Teraz odświeżę raz jeszcze, ale szybko wpisze tutaj clearTimeout, bo ta zmienna jest
dla nas globalnie dostępna,
bo jak widzisz tutaj, jesteśmy w tym globalnym zakresie.
Nie mamy tuaj żadnej funkcji,
czyli raz jeszcze odświeżę i teraz ten kod wykonam przed upływem pięciu sekund,
clearTimeout.
Jak widzisz 5 sekund już minęło, a nie wykonała nam się nasza funkcja.
Czyli jest to ciekawe, że taki timeout możemy sobie zresetować właśnie funkcją clearTimeout.
Ale musimy jej podać tutaj referencje do tego co zostało tutaj zwrócone.
Teraz kolejną funkcją, którą chciałbym Ci pokazać jest setInterval i ona działa nieco inaczej bo Timeout
działa w ten sposób, że mówimy wykonaj tę funkcję po pięciu sekundach np. jednokrotnie i koniec.
Natomiast setInterval pozwala wykonywać daną funkcję, co jakiś czas, czyli w takich właśnie interwałach
i ona wygląda podobnie. Natomiast tym razem utworzymy sobie funkcję, którą nazwę tick. Wcześniej utworze
jeszcze zmienną nazwiemy ją counter i ona będzie miała wartość 0, aby ci to dobrze pokazać i będę chciał,
aby funkcja tick zwiększała nam ten counter i go wyświetlała, czyli console.log counter++, uczyłem cię
już o tej implementacji, więc wiesz, co tutaj się stanie. Otóż wyświetlimy wartość np. 0 i zwiększymy ją
o 1.
Za następnym razem to już będzie 1, więc wyświetlimy i zwiększymy do dwóch i teraz odwołamy się do
setInterval.
I tutaj tak samo, jak w przypadku setTimeout podajemy funkcję.
No więc możemy podać do niej referencje, tak jak ci mówiłem,
czyli w ten sposób, podajemy tutaj i następnie czas w jakim chcemy, aby to się wykonywało 1000 milisekund,
czyli chcę, aby ta funkcja wykonywała się, co sekundę.
Przejdźmy do przeglądarki.
Zobaczymy.
No i mamy 0, 1, 2, 3 i tak dalej. Natomiast nie jesteśmy w stanie w tym momencie zatrzymać tego interwału.
On będzie w nieskończoność się wykonywał, więc co możemy tutaj zrobić.
Otóż znowu moglibyśmy tutaj odwołać się do lekkiej zmiennej. Tak jak tutaj timeout i do niej przypisać
to, co znajduje się tutaj w tym interwale. Ja jednak utworze zmienną troszkę wyżej, w tym miejscu. Nazwał
ją clock, przypiszę
na początku wartość null, również moglibyśmy nic nie przypisywać, nie ma to większego znaczenia.
I teraz będę chciał wywołać właśnie setInterval przypisując ją do clock,
ten oto sposób, natomiast co będziemy chcieli zrobić, aby móc zatrzymać cały ten interwał, będziemy chcieli
tutaj mieć pewien warunek.
Czyli jeżeli counter jest mniejszy lub równy zero, no to będziemy chcieli tak jak wcześniej zwiększać
jego wartość i ją wyświetlać. Natomiast kiedy dojdziemy do wartości 6, tutaj miało być 5, a nie 0.
Chcę do 5 odliczać, jeżeli dojdziemy do wartości 6, bo ona jest zwiększana, to będziemy chcieli ten
interwał wyczyścić, czyli else, będę mógł napisać clearInterval,
w ten sposób, tutaj mieliśmy clearTimeout, tutaj clearInterval. On jest przechowywany w clock, czyli odwołam
się do clock, będziemy chcieli go wyczyścić.
Zróbmy sobie to w ten sposób.
Czyli jakby tutaj wywołujemy tę funkcję setInterval i mówimy wywołał i funkcję tick co sekundę.
Funkcja tick się wykonuje.
Sprawdza jaką wartość ma counter, 0.
Ok, wykonaj console.log i zwiększ counter i za którymś razem counter będzie miał wartość 6, więc przejdziemy
tutaj i wyczyścimy
ten właśnie interwał. Odświeżmy i sprawdźmy czy ma to sens.
Powinniśmy tutaj dojść maksymalnie do wartości 5.
Zobaczymy.
No i tak też się stało.
Obliczyliśmy do pięciu i ten interwał został zatrzymany.
Teraz jedna bardzo ważna uwaga, bo będziesz mógł się spotkać w różnych publikacjach
z takim twierdzeniem, że lepiej używać zawsze timeout a nie interval,
chociaż jak widzisz timout wykonuje funkcję wyłącznie raz, a interwał wykonuje tę funkcję co jakiś czas,
więc jak możemy zastąpić interval, czyli setInterval, poprzez setTimeout.
Teraz będę chciał ci to pokazać.
Przejdziemy sobie tutaj,
poniżej. Ja może to wykomentuje, żeby się to już nie ustawiało.
Wpiszmy counterowi raz jeszcze wartość zero dla pewności, czyli mamy counter, który ma wartość 0.
I teraz będę chciał stworzyć funkcję.
Tutaj mieliśmy tick, więc następną nazwę tock np. i ona będzie korzystać z setTimeout, a nie setInterval.
Ja jeszcze za moment powiem ci dlaczego to jest lepsze rozwiązanie, bo zacząłem o tym mówić, ale najpierw
pokażę ci w jaki sposób to będzie działać.
I tutaj będę chciał sprawdzić znowu warunek if counter mniejszy lub równy 5.
Jeżeli jest mniejszy lub równe 5, to będę chciał zrobić console.log counter plus, plus, to co wcześniej, w ten sposób
i będę chciał zrobić jeszcze jedną rzecz, mianowicie setTimeout i będę chciał ustawić funkcję tock na
sekundę.
Teraz możesz się domyślić, że jeżeli wywołamy funkcję tock, to ona sprawdzi wartość counter i jest mniejsza
od 5, więc zwiększymy ją, wyświetlmy w console.log i ustawiamy timeout, czyli jednorazowo funkcję na
tock. Właśnie na tę samą funkcję.
Jest to swego rodzaju rekurencja, no więc po sekundzie znowu ta funkcja się wykona, znowu sprawdzi ile ma
counter, ma 1, ok, więc znowu możemy ustawić timeout, czyli tak jak wspomniałem timeout ustawia się tylko
raz, ale teraz za każdym razem będzie on ustawiany. Natomiast za którymś razem wartość znowu będzie miała
6.
Przejdziemy tutaj i cały ten kod się nie wykona, więc timeout nie zostanie ustawiony.
Jak widzisz tutaj, nie musimy go w żaden sposób resetować.
Jedyne co musimy zrobić to wywołać funkcję tock.
W ten sposób, czyli za pierwszym razem ją wykonać, a on ustawi timeout na samą siebie.
Sprawdźmy czy ma to sens i powinno nam to również się zatrzymać na piątce.
No i dokładnie tak się stało i teraz na koniec wytłumacze ci dlaczego jest to lepsze rozwiązanie.
Nie zawsze będziemy ustawiać timeout na taką długą wartość jak sekunda.
Czasem te timeout'y są ustawione np. na 10 milisekund, a kod, który się wykonuje też potrzebuje jakiegoś
czasu, aby został przez procesor komputera przetworzony.
I teraz jeżeli ustawimy setInterval to teoretycznie przy bardzo małych czasach, możemy zapchać kolejkę
tych zadań do wykonania.
Z tego powodu przejdźmy sobie to, gdzie było to ustawione, że gdybyśmy powiedzieli wykonuj tick np. co 10
milisekund, to jeżeli w funkcji tick będą jakieś cięższe obliczenia, czy więcej kodu, to może się tak zdarzyć,
że ona się nie wykona w ciągu tych 10 milisekund.
Jako funkcja, a jest ustawione, że znowu ma się wykonywać następna i następna i następna.
Czyli teoretycznie tą kolejkę możemy zapchać.
Natomiast w przypadku setTimeout tak nie będzie, bo ustawiamy tutaj tock na np. 10 milisekund i ta
funkcja będzie miała tutaj różny kod.
On się wykonuje i nie ma takiej możliwości, że zanim on się wykona to już jest kolejce
kolejny tock, dlatego że ten kod się wykonuje z góry na dół
i jak dojdzie do setTimeout, no to znaczy, że to co było nad tym się już wykonało, znowu ustawi tock, czyli
teoretycznie, jeśli to ustawimy coś na 10 milisekund, może się zdarzyć, że nie będzie to co 10 sekund milisekund wykonywane
ale np. co 12, bo ten kod, który tutaj się będzie znajdował będzie potrzebował więcej czasu na wykonanie.
Mam nadzieję że to rozumiesz.
Natomiast jak ten kod się wykona, to wtedy zostanie to ustawione dalej, a nie będzie zapychane takim interwałem
tak jak tutaj.
Czyli teoretycznie możemy nie korzystać w ogóle z setInterval, tylko setTimout.
Właśnie w taki oto sposób, jak pokazałem to tutaj.
setTimeout i setInterval · 1 min
// setTimeout(function() {
// console.log("Witaj po dwóch sekundach!");
// }, 2000);
var timeout = setTimeout(function() {
console.log("Witaj po pięciu sekundach!");
}, 5000);
clearTimeout(timeout);
var counter = 0,
clock = null;
function tick() {
if(counter <= 5) {
console.log(counter++);
} else {
clearInterval(clock);
}
}
// clock = setInterval(tick, 1000);
counter = 0;
function tock() {
if(counter <= 5) {
console.log(counter++);
setTimeout(tock, 1000);
}
}
tock();