JavaScript jest językiem skryptowym, w odróżnieniu od PHP wykonywanym po stronie klienta i stanowi podstawę interaktywnych stron WWW.
Składnia JS przypomina tę znaną z języka C czy Java. JS wprowadza elementy obiektowości, a do jego podstawowych mechanizmów należą:
JavaScript posiada również bogatą bibliotekę funkcji wbudowanych, służących m.in. do obsługi zegara czy operacji matematycznych. Problem wymiany danych przez aplikację działająca w przeglądarce użytkownika z serwerem rozwiązywany jest przez metodologię AJAX, polegającą na wykonywaniu z poziomu JavaScript zapytań HTTP bez widocznego dla użytkownika przeładowania strony. AJAX będzie stanowił jeden z tematów kolejnych zajęć.
Służy do tego polecenie ltsp-localapps
, np.:
ltsp-localapps firefox ltsp-localapps google-chrome --proxy-server=10.0.0.254:3128
Ważne jest ustawienie proxy na 10.0.0.254:3128
- polecenie dla Chrome posiada już odpowiedni switch.
Obiektowy Model Dokumentu (DOM - Document Object Model) jest strukturą drzewiastą przechowującą obiekty reprezentujące wszystkie elementy strony. Korzeniem części drzewa odpowiedzialnej za sam dokument HTML jest obiekt globalny document
.
Firebug jest niezwykle użytecznym narzędziem dla developerów. Proszę uruchomić Firefoksa poleceniem:
firefox &
Na serwerze borg zainstalowany jest Firefox (iceweasel) w wersji 3.0.6, natomiast na serwerze charon w wersji 2.0.0.19. Najnowszą wersją Firebuga współpracującą z przeglądarką w wersji 3.0.6 jest wersja 1.4.5, natomiast dla wersji Firefoxa 2.0.0.19 proszę użyć Firebuga w wersji 1.3.1. Proszę zainstalować odpowiednią wersję Firebuga i ponownie uruchomić przeglądarkę. W prawym dolnym rogu pojawi się ikonka, po kliknięciu której otwiera się na dole panel Firebuga.
Na początek, proszę przygotować plik HTML o następującej treści:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Lab JS</title> </head> <body> <form name="formularz"> <p id="akapit"><input type="button" value="Rysuj!"></p> </form> </body> </html>
Proszę otworzyć panel Firebuga i włączyć konsolę. Konsola pozwala na wpisywanie dowolnych wyrażeń i poleceń JavaScript i wykonywanie ich w czasie rzeczywistym. Proszę wpisać:
document
W odpowiedzi, FireBug zwróci referencję do obiektu klasy Document. Po kliknięciu tego linku prawym klawiszem można wybrać opcję Zbadaj w karcie DOM.
W zakładce DOM można przeglądać i zmieniać właściwości obiektu oraz jego metody:
Proszę, poprzez edycję odpowiedniej właściwości, zmienić tytuł strony pojawiający się w pasku tytułowym okna przeglądarki.
Parametry te zmieniać można również przy pomocy samego kodu JS, np.:
document.title = "Ala ma kota"
JavaScript posiada funkcje pozwalające na dotarcie do konkretnych obiektów w drzewie DOM:
name
,Proszę sprawdzić działanie następujących poleceń:
document.getElementById('akapit'); document.getElementsByName('formularz'); document.getElementsByName('formularz')[0]; document.getElementsByTagName('input'); document.getElementsByTagName('input')[0]; document.getElementsByTagName('input')[0].type;
Proszę zwrócić uwagę jakie opcje pojawiają się w menu kontekstowym linku do określonego obiektu, m.in. Badaj w karcie HTML i Badaj w karcie DOM.
Proszę, przy pomocy jednego polecenia JS, wstawić napis z przycisku do paska tytułu przeglądarki.
Każdy element HTML, który „w środku” posiada jakąś wartość, posiada też atrybut innerHTML, przechowujący kod HTML tej wartości. Proszę spróbować:
document.getElementById('akapit').innerHTML;
Każdy obiekt w DOM posiada składową style
, przechowującą jego wszystkie parametry CSS. Proszę wydać polecenie:
document.getElementById('akapit').style;
Firebug pozwala na badanie obiektów klasy CSSStyleDeclaration w zakładce CSS oraz w zakładce DOM. Ponieważ akapit nie posiada przypisanego stylu, w zakładce CSS nie pojawi się nic – proszę więc otworzyć zakładkę DOM i przejrzeć wszystkie (puste) właściwości tego obiektu. Czy ich nazwy coś Państwu przypominają?
Proszę zmodyfikować styl akapitu poprzez ustawianie odpowiednich wartości określonych właściwości obiektu (w zakładce Konsola).
Top Tip |
---|
Kolory w CSS można wyrazić przy pomocy ciągów znaków o następującej postaci: 1. nazwa koloru (wg. specyfikacji), 2. jak w „starym” HTML (np. #10DE34 ) albo w postaci skróconej (#0E8 = #00EE88 ), 3. jako składowe RGB: przy pomocy wartości 8-bitowych (np. rgb(132,52,58) ) lub jako wartości procentowe (np. rgb(0%,20%,38%) ). |
JS pozwala też na ingerencję w strukturę DOM, tzn. dodawanie i usuwanie obiektów. Do tworzenia nowych elementów strony służy metoda createElement
obiektu DOM.
Proszę wykonać polecenie:
document.createElement('div');
Polecenie to jednakże nie dodaje elementu do dokumentu, a jedynie tworzy nowy obiekt w pamięci i zwraca do niego referencję. Ponieważ DOM ma strukturę drzewiastą, taki nowo utworzony element należy dodać jako dziecko jednego z już istniejących elementów. (Dobrym pomysłem będzie tworzenie nowych elementów jako dzieci obiektu document.body
)
Proszę ponowić polecenie, ale zapamiętując w zmiennej (np. mojElement
) referencję do nowo utworzonego obiektu:
var mojElement = document.createElement('div');
Teraz proszę dodać jakiś tekst do wartości atrybutu innerHTML tego obiektu, a następnie dodać go do drzewa DOM:
document.body.appendChild(mojElement);
JavaScript posiada bogatą bibliotekę funkcji matematycznych. Proszę sprawdzić działanie następujących poleceń:
Math.floor(2.54); Math.ceil(2.54); Math.round(2.54); Math.floor(-2.54); Math.ceil(-2.54); Math.round(-2.54); Math.min(4, 6, 2, 10); Math.random();
JS udostępnia też kilka użytecznych stałych, m.in.:
Math.E; Math.PI;
Proszę przygotować polecenie, które generuje losowe liczby całkowite z zakresu 0-255.
Funkcje JS umieszcza się w pliku HTML najczęściej w sekcji head
:
Aby umieścić kod JS bezpośrednio, należy dodać następujący kod:
<script type="text/javascript"> function mojaFunkcja(tekst) { console.log('Wywołanie funkcji z parametrem: ' + tekst); } </script>
Top Tip |
---|
W powyższym kodzie „przy okazji” proszę zwrócić uwagę na dwie rzeczy. Po pierwsze, skorzystaliśmy z obiektu console , udostępnianego przez wtyczkę Firebug, aby pisać bezpośrednio na konsolę. Jest to bardzo użyteczne narzędzie przy debugowaniu tworzonych aplikacji webowych. Po drugie, konkatenacji stringów w JS dokonuje się przy pomocy operatora + . |
Alternatywnie, zawartość elementu script
można umieścić w osobnym pliku, np. skrypty.js
i zmodyfikować ten kod w następujący sposób:
<script type="text/javascript" src="skrypty.js"></script>
Takie wywołania często stosuje się do dołączania „hostowanych” wersji popularnych bibliotek JS, takich jak jQuery, Prototype czy Google Maps API.
Proszę napisać funkcję, która po wywołaniu dodaje do dokumentu (a dokładnie obiektu body
) nowy element typu akapit (p
), zawierający jakiś określony, stały tekst i losowy kolor tła.
Interaktywność stron WWW (m.in. takich jak GMail) wykorzystujących JS oparta jest w dużej mierze na tzw. zdarzeniach (ang. events). Każdy obiekt posiada zbiór zdarzeń, na które może zareagować. Do najczęściej wykorzystywanych zdarzeń należą:
Procedurę obsługi zdarzenia można przypisać do obiektu bezpośrednio w kodzie HTML, na przykład::
<div onclick="alert('OMG! They clicked Kenny!');">Kenny</div>
Top Tip |
---|
Przy okazji proszę zwrócić uwagę na wywołanie funkcji alert. JavaScript posiada też dwie podobne do niej funkcje - prompt oraz confirm. |
Zmodyfikuj kod strony tak, aby po kliknięciu przycisku wywoływała się funkcja napisana w poprzednim ćwiczeniu.
Procedura obsługi określnego zdarzenia do danego obiektu może też zostać przypisana dynamicznie w kodzie JS, np.:
document.getElementsByTagName('p')[0].onclick = function(e) { console.log(e); }
Powyższy fragment kodu przypisuje do pierwszego elementu typu p
na stronie funkcję obsługi zdarzenia. Do takiej funkcji zawsze przekazywany jest parametr – referencja do obiektu przechowującego parametry zdarzenia (w przykładzie nazywa się e
). W funkcji znajduje się polecenie wypisania referencji tego obiektu w konsoli Firebuga. Proszę przejrzeć własności tego obiektu w zakładce DOM Firebuga.
Atrybut target przechowuje referencję do obiektu, który został kliknięty. Można więc dotrzeć do wszystkich atrybutów tego obiektu.
Proszę zmodyfikować kod z poprzedniego zadania tak, aby przypisać do zdarzenia onclick
tworzonych akapitów wywołanie funkcji. Funkcja ta powinna wyświetlać okienko typu alert, zawierające wartość atrybutu CSS background-color
klikniętego obiektu.
Proszę zmodyfikować funkcjonalność nowo tworzonych akapitów tak, aby po najechaniu na nie myszką ich kolor zmieniał się na inny, losowy.
JS pozwala na definiowanie zmiennych globalnych. Zmienne te są widoczne z poziomu każdej funkcji; zasięg widoczności zmiennej ustalany jest podobnie jak w języku C, tzn. zmienna zadeklarowana poza funkcją jest widoczna w obrębie całego kodu, np.:
... <head> <script type="text/javascript"> var x = 5; function display() { window.alert(x); } </head> </script> Jak widać, zmienną taką można również zainicjalizować wartością. Zmienne globalne są użyteczne do zapamiętywania stanu różnych wartości, takich jak różne liczniki czy timery (o tym w kolejnych zadaniach). W rzeczywistości, zmienne globalne są składowymi obiektu ''window'': <code javascript> var myValue; function setValue() { myValue = "test"; } function getValue() { alert(window.myValue); }
Proszę wykonać powyższy kod i zwrócić uwagę, jak „dostajemy się” do zmiennej myValue
w jednej i w drugiej funkcji.
Javascript dostarcza także mechanizmy kontroli czasu. Możemy np. określić wykonanie jakiegoś kodu po określonym czasie. Do tego celu służą zdarzenia czasowe, w obiekcie window:
Ich użycie jest następujące:
var id = setTimeout("polecenie javascript",liczba_milisekund);
Metodą setTimeout
uruchamiamy proces odliczania czasu. Metoda ta zwraca identyfikator konkretnego procesu odliczania, zatem używając jej możemy uruchomić więcej niż jeden proces odliczający czas. Ustalając dla każdego procesu indywidualny identyfikator, możemy każdy z tych procesów przerwać stosując metodę clearTimeout()
, argumentem której powinien być wspomniany identyfikator danego procesu.
Wypróbuj działanie następującego kodu:
var moj_stoper = setTimeout("console.log('krok')",3000);
oraz
var moj_stoper = setTimeout("console.log('krok')",3000); clearTimeout(moj_stoper);
Wykorzystując rekurencję, możemy stworzyć licznik czasu przebywania na stronie:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Lab JS liczniki czasu</title> <script type="text/javascript"> <!-- var czas = -1 function odliczaj(){ czas++ document.getElementById('czas').innerHTML = czas; setTimeout("odliczaj()",1000); } // --> </script> </head> <body onload="odliczaj()"> <p><span>Licznik czasu: </span><span id="czas">0</span></p> </body> </html>
TOP TIP |
---|
Zauważ, w jaki sposób pierwszy raz wywołana została funkcja odliczaj() ! Wykorzystane zostało zdarzenie zachodzące w momencie wczytania (pobrania) strony internetowej do przeglądarki. |
Dodaj do powyższego skryptu funkcjonalność wypisującą słownie słowo „sekunda” uwzględniając koniugację np. 1 sekunda, 2 sekundy, …, 5 sekund, itp.
Kierowcy Formuły 1 ćwiczą swój refleks i koordynację na specjalnej maszynie - Batak. Ćwiczenie to polega na naciskaniu podświetlających się przycisków w jak najkrótszym czasie. Stwórz komputerowy symulator urządzenia Batak.
Pojedynczy czas reakcji (w sekundach) można obliczyć w następujący sposób:
var czasStart = new Date(); ... var czasStop = new Date(); var czasReakcji = (czasStop.getTime()-czasStart.getTime())/1000
Szkielet strony HTML do napisania programu znajduje się poniżej:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Lab JS batak</title> <style type="text/css"> div#d1, div#d2, div#d3, div#d4 { background-color: red; width: 50px; height: 50px; position: absolute; } div#d1 { top: 10px; } div#d2 { right: 10px; } div#d3 { bottom: 10px; } div#d4 { bottom: 10px; right: 10px; } div#srodek { text-align: center; } </style> </head> <body> <div id="d1" onclick="wcisnieto(1)"></div> <div id="d2" onclick="wcisnieto(2)"></div> <div id="d3" onclick="wcisnieto(3)"></div> <div id="d4" onclick="wcisnieto(4)"></div> <div id="srodek"> <form action="#"> <p><input type="button" value="start" onclick="start()" /></p> </form> <p id="komunikat"></p> </div> </body> </html>
Dany jest plik HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Drag and Drop!</title> <style type="text/css" media="screen"> body { background-color: #DDD; } #kwadrat { position: absolute; left: 100px; top: 100px; width: 100px; height: 100px; background-color: red; cursor: pointer; } </style> <script type="text/javascript" charset="utf-8"> // tu będą skrypty... </script> </head> <body> <div id="kwadrat"></div> </body> </html>
Celem tego zadania jest zrealizowanie funkcjonalności drag & drop, czyli umożliwienie użytkownikowi przeciągania czerwonego kwadratu w dowolne miejsce okna przeglądarki.
Funckjonalność ta powinna być zrealizowana w oparciu o zdarzenia onmousemove
(ruch myszą), onmousedown
(wciśnięcie przycisku myszy) oraz onmouseup
(puszczenie przycisku myszy), przypisane do kwadratu (patrz ćwiczenia 6 i 7).
Najważniejszą rzeczą do zrobienia jest przesuwanie kwadratu do określonego miejsca. Przejrzyj atrybuty obiektu o id kwadrat
w zakładce Inspektor DOM. Spróbuj, korzystając z konsoli, opracować metody przesuwania kwadratu o odpowiednią odległość w wybraną stronę przy pomocy JavaScript.
Uwaga: funkcja w zdarzeniu onmousemove
nie powinna zawsze przesuwać kwadratu. Przesuwanie powinno być realizowane tylko jeżeli użytkownik kliknął na kwadrat i trzyma wciśnięty przycisk myszy. Przyda się do tego zmienna globalna (patrz ćwiczenie 8), przechowująca informację o tym czy obiekt jest obecnie przeciągany czy nie.