JavaScript jako element strony internetowej
Struktura strony internetowej
W projekcie każdej strony internetowej można wyróżnić trzy główne aspekty (warstwy): treść (content), wygląd (styl) oraz sposób zachowania (dynamika).
Treść opisujemy przy pomocy języka HTML a wygląd za pomocą CSS. Za aspekt dynamiczny odpowiada głównie JavaScript.
Mówiąc o dynamicznych zmianach i JavaScrpt trzeba pamiętać, żemowa jest tu o zmianach (ruchu) w aktualnie oglądanej stronie (po jej wczytaniu). Nie należy tego utożsamiać z podziałem stron na statyczne i dynamicze. Strony dynamiczne to takie, które są tworzone na serwerze z danych - najczęściej pamiętanych w bazie danych. Takim tworzeniem stron zajmują się na przykład systemy CMS, których popularnym przedstawicielem jest Wordpress. Tym nie będziemy się zajmowali (tak zwany backend). Wspominamy o tym wyłącznie dlatego, aby pokazać typowy kontekst użycia JavaScript.
Dygresja: Strony statyczne to takie, które nie są tworzone przez programy w trakcie wczytywania, ale ich treść została wcześniej w pełni przygotowana i zapisana w plikach HTML i CSS. Takie strony także mogą siż zmieniać – na przykład przy zmianie wielkości ekranu. Strony dynamiczne to takie których zachowanie lub wygląd definiuje program. Tu sprawa nieco się komplikuje, bo program może być wykonywany przez przeglądarkę internetową (frontend) lub serwer www (backend). W niniejszym podręczniku mowa właśnie o tym, co dzieje się po stronie frontendu -gdzie używany jest JavaScript. Czy stronę zawierającą bogatą aplikację w JavaScript nazwać statyczną czy dynamiczną? To nie ma większego znaczenia (często przyjmuje się po prostu, że dynamiczne = z treścią pamiętaną w bazie danych).
Krótki wstęp do HTML
Pierwotnie wzorem dla stron internetowych były teksty tworzone w edytorach (takich jak Word), które dzielone są na paragrafy. Do zbudowania strony wystarczałyznaczniki (ang. “tag”):
podział na paragrafy (p);
załamanie wiersza (br);
podkreślenia, kursywa, wytłuszczenia (u,i,b);
nagłówki (h1,h2,...);
linki (a);
wyliczenia i numerowania (ul, ol, li);
wstawienie obrazka (img);
tablice (table, tr,th,td);
formularze (form, input, button);
Każdy znacznik ma dwa warianty – określające początek I koniec tekstu. Na przykładzie znacznika p:
<p>
- początek paragrafu
</p>
- koniec paragrafu
Czyli używamy znaków mniejszy (<) I większy (>) aby odróżnić znacznik od reszty tekstu. Aby uniknąć pomyłek – w tekście (poza znacznikami) zamiast znaku mniejszości stosujemy zapis: <.
Przykład paragrafu w HTML:
<p><b>2/5 jest < niż 2/3</b></p>
Z czasem strony internetowe zaczęły przypominać publikacje drukowane: podzielone na ramki.
Do określenia ramek stosuje się znacznik div.
<div>
<div>
ramka 1
</div>
<div>
ramka 2
</div>
</div>
Domyślnie ramki ustawiają się jedna pod drugą.
Fragmenty tekstów w obrębie ramek można wyróżniać znacznikiem span.
Na przykład:
To jest <span> wyróżniony tekst</span>
Sposób wyświetlania ramek i tekstów (span) ustawia się przy pomocy styli - czyli własności znaczników o nazwie "style"
Przykład:
<div>To jest <span style="color:red">czerwony tekst</span></div>
Na tym przykładzie widać, że własnośćznaczników to dodatkowy opis między znakami <> - po identyfikatorze znacznika i oddzielony od niego spacją.
Przykłady własności niektórych znaczników:
<a href="adres internetowy strony">
<img src="adres internetowy zdjęcia" alt="opis zdjęcia>
<form action="adres internetowy dokąd wysyłamy dane z formularza" method="sposób wysyłania">
Oczywiście w miejsce opisów jak powyżej należy wpisać konkretne informacje.
W przypadku formularza (form) pokazano jak podzielić opis znacznika na dwa wiersze. Sposób wysyłania w tym znaczniku może być określony słowem "GET" lub "POST" (zalecane).
Poza wspomnianymi powyżej, najczęściej stosujemy własności identyfikujące znacznik. Mamy przy tym dwa rodzaje własności identyfikatorów :
- identyfikator konkretnego znacznika: id
- identyfikator klasy: class
Przykład:
<div id="ramka1">
To jest <span class="kolorowe_teksty" style="color:red">czerwony tekst</span>
</div>
Poza własnościami styli i identyfikatorów niezbędne są:
własność href - dla znacznika
<a>
- określa link (URL) docelowywłasność src dla znacznika
img
- określa adres grafikiwłasności związane z formularzami (
action, method, type, value, name
)własności związane z tabelami (na przykład łączenie komórek).
Dodatkowo w dalszej części podręcznika pojawią się własności opisujące zdarzenia związane z funkcjonowaniem strony. Na przykład własność „onclick” opisuje co stanie się, gdy w element opisany znacznikiem klikniemy myszką. Stosowanie pozostałych rodzajów własności nie ma dla nas większego znaczenia.
Dla zainteresowanych - więcej szczegółów można znaleźć na przykład w podręczniku:
http://homeproject.pl/wp-content/uploads/2018/01/Podrecznik-HTML-CSS-2.pdf
Jednak powyższy zakres wiedzy naprawdę nam wystarczy aby zacząć przygodę z JavaScript.
Style
Atrybuty wyświetlania (na przykład kolor) można ustawiać za pomocą styli css. Na przykład <p style="color:red;font-weight:bold">.
Wróćmy do opisanych wcześniej ramek, aby pokazać jak za pomocą styli można określić ich atrybuty:
<div style="border: 1px solid blue;">
ramka 1
</div>
<div style="border: 1px solid red;">
ramka 2
</div>
<div style="border: 1px solid green;">
ramka 3
</div>
W powyższym przykładzie opisano kolorowe obramowania. Podobnie możemy zmieniać teksty określone przez "span". Na przykład:
<span style="color:blue">
tekst niebieski
</span>
Aby ustawić je obok siebie - wykorzystuje się atrybuty szerokości i przepływu (float):
<div style="border: 1px solid;width:40%;float:left">
ramka 1
</div>
<div style="border: 1px solid;width:40%;float:left">
ramka 2
</div>
<div style="border: 1px solid;width:40%;float:left">
ramka 3
</div>
<div style="clear:both;">
</div>
</div>
Aby odróżnić identyfikatory klas i znaczników poprzedza się je znakiem kropki (klasa) lub "płotka" (#). Dzięki temu możemy zapisać style w odrębnej sekcji html, opisując identyfikatorami to, co chcemy zmieniać:
<style>
#ramka1 { background-color:"yellow"; }
.kolorowe_teksty{font-weight:bold;}
</style>
Język opisu styli CSS jest bardzo bogaty. Nie ma sensu uczyć się wszystkich atrybutów na pamięć - gdyż istnieje wiele dostępnych on-line podręczników.
Podręczniki CSS:
https://pl.wikibooks.org/wiki/CSS
https://www.w3schools.com/css/default.asp(angielski, z dobrym tłumaczeniem Google)
JavaScript
Porównując bogactwo podręczników z powyższym krótkim opisem może to wydawać się dziwne, ale naprawdę powyższe informacje wystarczą do tworzenia stron internetowych - poza formularzami i elementami zmienianymi dynamicznie. Do tego służy właśnie JavaScript.
Mamy zatem trzy podstawowe elementy strony internetowej:
- treść: html
- wygląd (styl): css
- dynamikę: javascript
Wywołanie skryptu występuje wskutek wydarzenia - na przykład załadowania strony lub kliknięcie w jakiś jej element.
Kilka ważnych pojęć
Nawigacja
Zmiany w naszej przeglądarce najczęściej polegają na nawigacji – czyli przechodzeniu od strony do strony. Sterujemy tym używając przede wszystkim linków (url, znacznik a) oraz formularzy (znacznik form i input). Javascript umożliwia modyfikację strony bez jej przeładowywania.
Renderowanie
Renderowanie – tworzenie wyglądu na podstawie opisu. Zazwyczaj pojęcie to odnosi się do tworzenia wyglądu przez przeglądarkę internetową.
Renderowanie w przeglądarce zaczyna się po pobraniu kodu HTML i CSS. W narzędziach dla webmasterów firmy Google (https://www.google.com/webmasters/tools/) można znaleźć „zobacz jako Google”, które pozwala sprawdzić, czy nasza strona jest tak samo widziana przez użytkownika jak i przez przeglądarkę. Jest tam opcja „renderuj”. Szczegółowy opis tego procesu (po angielsku): https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/.
Drzewo DOM
Renderowanie w przeglądarce rozpoczyna się od zbudowania drzewa DOM na podstawie znaczników HTML. Drzewo – bo znaczniki są zagnieżdżane (tworzą strukturę drzewa). Zobaczmy jak to wygląda dla prostej strony
(źródło):
<html>
<head>
<meta charset="utf-8">
<link href="style.css" rel="stylesheet">
<title>Critical Path</title>
</head>
<body>
<p>Hello <span>web performance</span>
students!</p>
<div><img src="awesome-photo.jpg"></div>
</body>
</html>
Obiekty
Każdy węzeł (node) tego drzewa (zaznaczone na żółto) jest obiektem. Czyli nie tylko jest to prosta wartość (jak liczba), ale zawiera własności (na przykład identyfikator). Na popielato zaznaczono jedną z własności - wyświetlaną treść.
Abstrakcyjne pojęcie obiektu jest obok zmiennej jednym z najważniejszych w informatyce. Zmienna to fragment pamięci komputera oznaczony nazwą. Obiektem jest struktura, która ma swoje własności (które także mogą być obiektami) i metody zmian tych własności (więcej:Programowanie : Uczymy_się myśleć abstrakcyjnie).
Ważne jest aby rozróżniać obiekt i klasę obiektów. Na przykład mamy obiekt Jana Kowalskiego klasy Student, która jest podklasą Ludzi. W przypadku drzewa DOM mamy klasy obiektów zdefiniowane przez znaczniki (np. div). Drzewo DOM jest obiektową strukturą strony internetowej (zob:https://pl.wikipedia.org/wiki/Obiektowy_model_dokumentu).
Uwaga terminologiczna.Nie należy kojarzyć klasy obiektów w drzewie DOM z własnością znaczników o nazwie„class”.Węzły drzewanie sąklasamidefiniowanymiprzez atrybut / własność znacznikówclass. Nazwa klasy znaczników (własność class) uważana jest na poziomie drzewa DOM za własność obiektów (węzłów drzewa). Przez analogię można to porównać do nazwisk ludzi. Nazwisko to własność każdego człowieka, ale pozwala też wyróżnić grupę ludzi o takim samym nazwisku. Gdyby w języku polskim zamiast słowo "nazwisko" funkcjonowało słowo "klasa", to mielibyśmy podobny kłopot z wyjaśnieniem pojęcia "klasy ludzi". Gdy mowa o DOM - można po prostu na chwilę zapomnieć o słowie "class" i traktować klasę jako rodzaj znacznika.
Program w JavaScript może odczytywać i zmieniać własności drzewa DOM.
Zdarzenia
Wiemy już do czego służy JavaScript. Jak jednak są uruchamiane programy napisane w tym języku? Są one wywoływane do obsługi zdarzeń. Na przykład najechania myszką na element strony lub kliknięcia w przycisk.
Zdarzenia obsługujemy skryptami napisanymi w JavaScript.
Funkcja
Absurdem byłoby, gdyby każde zdarzenie powodowało uruchamianie całego programu / skryptu zapisanego w Javascript. Dlatego naturalnym jest podział skryptu na drobne fragmenty służące do różnych celów. Fragmentom tym nadajemy najczęściej identyfikator, którym posługujemy się aby go wskazać. Taki fragment skryptu nazywamy funkcją. Ma on zapis następujący:
function identyfikator(parametry) {
fragment skryptu
}
Typowy program Javascript może składać się z wielu funkcji. Funkcje nazywa się także czasem procedurami (w niektórych innych językach procedura to szczególny rodzaj funkcji – taka która nie zwraca żadnej wartości).
Identyfikatory
Aby móc odwoływać się do konkretnych obiektów, czy funkcji – musimy je jakoś nazywać. Do tego służą identyfikatory. Do ich tworzenia możemy użyć liter łacińskich (polskie znaki wykluczone), cyfr oraz znaków podkreślenia (_) I dolara ($). Pierwszym znakiem identyfikatora nie może być cyfra.
Przykłady identyfikatorów: abc, dluga_nazwa, cyfra6, $pole.
Nie są poprawnymi identyfikatorami napisy: 6a, dług, „pole”.
Obiekty mogą mieć wewnętrzną strukturę składającą się z danych (zwanych własnościami) i funkcji (zwanych metodami). Odwołujemy się poprzez podanie ich identyfikatora po nazwie obiektu zakończonej kropką. Na przykład dla fikcyjnego obiektu reprezentującego człowieka możemy zdefiniować własność określającą jego wzrost: czlowiek.wysokosc, albo metodę wyświetlania informacji o nim: czlowiek.informacje()
.
Obiekty i funkcje wbudowane
Jak już wiemy – skrypty działają w środowisku przeglądarki internetowej, a identyfikatory pozwalają wskazywać obiekty i funkcje. W jaki sposób jednak powiązać nasz opis (kod programu) z tym co dzieje się na stronie? Służą do tego elementy „wbudowane” - czyli takie, których nie musimy definiować (opisywać), bo one już istnieją w chwili uruchomienia programu. Mają one swoje identyfikatory – zdefiniowane przez twórców standardów (Javascript).
Tyle teorii nam wystarczy.
Więcej informacji:
http://www.w3schools.com/html/html_intro.asp(można wybrać polskie tłumaczenie – jest dość porządne) .
http://pdf.helion.pl/e14te3/e14te3.pdf(rozdział 3.8 i dalej).
Przejdźmy do pierwszego przykładu, który pokaże nam jak stosować funkcje do obsługi zdarzeń.
Pierwszy przykład
Istnieje wiele stron internetowych umożliwiających śledzenie (testowanie) działania skryptów w Javascript.Na przykład:http://codepen.io/pen/, https://jsfiddle.net/, http://jsbin.com/.Skorzystajmy z: http://jsbin.com/folowenasa/edit?html,css,js,console,output
Wpiszmy w treść strony jakiś tekst – na przykład „Kliknij tutaj”.
Do znacznika <body>
dodajmy własność „onclick” i nadajmy jej wartość „test()
;”. Będzie to znaczyć, że po kliknięciu na stronie wykona się procedura (funkcja) „test”.
Przykład 1
<body onclick="test();">kliknij tutaj</body>
Procedura musi zostać napisana – żeby się wykonała:
function test() {
alert('!');
}
Poniższe tabelki zawierają opis wszystkich symboli użytych w tym programie:
body | Część języka HTML w którym opisujemy strony internetowe. W tym wypadku znacznik używany do ograniczenia całej strony. | Oznacza wnętrze (treść) strony. |
---|---|---|
< > | Dwa symbole określające początek i koniec znacznika. | Miejsce w tekście gdzie zaczyna się i kończy znacznik. |
/ | Zmienia znaczenie znacznika (koniec oznaczanego obszaru) – o ile występuje natychmiast po znaku < | |
onclick | Własność dodawana do znacznika. Po znaku = nadaje się tej własności wartość. | Co się stanie, gdy klikniemy na wskazywane przez znacznik miejsce. |
function | Symbol używany do zdefiniowania fragmentu kodu (programu) nazywanego funkcją. | Definicję jakiejś funkcji. |
test | Symbol zdefiniowany przez nas – konkretnej funkcji. | Definicję konkretnej funkcji test. |
alert | Wyświetlenie komunikatu | Funkcję zdefiniowaną (wbudowaną) w przeglądarce. |
Znaki używane dla interpretera (przeglądarki internetowej) – aby mógł jednoznacznie "zrozumieć" znaczenie tekstu:
Znak | Znaczenie |
---|---|
{ | Początek bloku (funkcji) |
} | Koniec bloku (funkcji) |
; | Koniec instrukcji (z których budujemy funkcję). |
" | Cudzysłów oznaczający początek i koniec napisu. |
= | Znak równości (lub nadanie zmiennej określonej wartości) |
( | Początek miejsca na parametry funkcji |
) | Koniec miejsca na parametry funkcji |
Jak widzimy - uruchomienie programu następuje wskutek jakiegoś zdarzenia. Tu wykorzystujemy zdarzenie „onclick”.
Znaczenie każdego symbolu zależy od kontekstu w którym go używamy. Słowo „alert” oznacza po angielsku alarm. W środowisku przeglądarki internetowej powoduje wyświetlenie komunikatu. Użycie symbolu w powyższym zdaniu jest jego przytoczeniem (cytatem). Po to używamy cudzysłowów. Jeśli w definicji funkcji test zmienimy alert(‘kliknąłem’) na alert(‘alert’) to nie wykona się dwa razy funkcja „alert”, tylko zostanie wyświetlona (przytoczona) jej nazwa.
Kontekst jest ważny, bo w różnych miejscach ten sam symbol może oznaczać coś innego. Nie należy tego nadużywać (lepiej stosować różne symbole).
Co się dzieje w przeglądarce internetowej
Najważniejszym zdarzeniem w przeglądarce jest załadowanie strony. Proces ten przebiega współbieżnie. Przeglądarka ściąga dane z serwera. Po ściągnięciu CSS i HTML rozpoczyna budowę drzewa DOM i renderowanie strony (dlatego mówi się, że CSS i HTML blokują renderowanie - proces rozpoczyna się po skompletowaniu CSS i HTML).
Po załadowaniu i zrenderowaniu strony jest ona wyświetlana – choć mogą być ściągane kolejne jej elementy (jak obrazki i skrypty JavaScript). Gdy przeglądarka uzna, że ma już komplet – wywołuje zdarzenie onload– na rzecz obiektu document (znacznik body). Zaleca się, aby skrypty które nie zawierają obsługi tego zdarzenia umieszczać nie w nagłówku, ale na końcu strony (wtedy onload zachodzi wcześniej - nawet gdy nie skończy się proces pobierania skryptów).
Poza onload najczęściej wykorzystuje się zdarzenie onclick wywoływane na rzecz obiektów z drzewa DOM (pełną listę darzeń umieszczono w dodatku A).
Przykład 2:
<html>
<head>
<meta charset="utf-8">
<script>
function zdarzenie1() {
alert("załadowałem");
}
function zdarzenie2() {
alert("kliknąłem");
}
</script>
</head>
<body onload="zdarzenie1()">.
<p>Kliknij
<a href="#" onclick="zdarzenie2()">tutaj</a>
</p>
</body>
</html>
Objaśnienie
Użyte w kodzie symbole:
Symbol | Znaczenie | oznaczanie |
---|---|---|
function | Symbol używany do zdefiniowania fragmentu kodu (programu) nazywanego funkcją (zob. dalej). | Definicję jakiejś funkcji. |
zdarzenie1 zdarzenie2 | Symbole zdefiniowane przez nas – nazwy funkcji. | Definicje funkcji (zdarzenie1 i zdarzenie2). |
alert | Wyświetlenie komunikatu | Funkcję zdefiniowaną (wbudowaną) w przeglądarce. |
Przykład operacji na drzewie DOM
Aby nasz opis funkcjonowania skryptów na stronie internetowej był kompletny – musimy pokazać jak operować na drzewie DOM. Ten przykład może wydać się nieco trudniejszy. Tak jest w istocie – dlatego wprowadzono wiele ułatwień (jak tak zwaną bibliotekę jQuery o której będzie mowa dalej).
Obiekt dokumentu (document) posiada metody pozwalające odszukanie węzła drzewa. Na przyład na podstawie identyfikatora (własność id). Wykorzystamy to, by znaleźć znacznik o identyfikatorze „test” i odczytać jego kolor (część definicji stylu wyświetlania).
Przykład 3:
<html>
<head>
<script>
function test() {
alert(document.getElementById("test").style.color);
}
</script>
</head>
<body>
<span style="color:blue" id="test" onclick="test();"> kliknij tutaj
</span>
</body>
</html>
W przykładzie tym kliknięcie w tekst powoduje wyświetlenie nazwy koloru. Możemy ten kolor też w JavaScript zmieniać:
document.getElementById("test").style.color = "red";