Obecně o skriptování

Chceme-li měnit informace na stránkách kupříkladu mezi jednotlivými přístupy, případně každému uživateli poskytovat jiné údaje, můžeme použít skriptování. Toto se může odehrávat na straně serveru i na straně klienta. Na straně serveru skriptem generujeme výsledný HTML-kód, na straně klienta je situace poněkud složitější (tam do vygenerovaného kódu zasahujeme), nicméně aby nebyla situace na serveru jednodušší, existuje mnoho možností skriptování na serveru. Na klientovi je situace jednodušší v tom smyslu, že až na patologické případy lze psát skripty nejvýše v Javascriptu (stranou ponecháváme Active X, VBScripty a podobné, jelikož první je lepší mít z bezpečnostních důvodů zakázané, kdežto druhé funguje jen občas na Internet Exploreru). Při psaní skriptů pro klient je vhodné myslet na to, že ne všechny prohlížeče náš skript budou schopny zinterpretovat, proto je vhodné stránky nezaložit jen ja Javascriptech, opak (tedy stránky na skriptování založené) je snadnou metodou, jak návštěvníka znechutit (je jen málo takových, kteří si budou kód interpretovat a domýšlet, co jste mínili udělat). Zkrátka Javascript, který nás bude v této kapitole zajímat, je dobrý sluha, ale špatný pán.

Tag SCRIPT

Skriptování na straně klienta provádíme buďto nastavováním handlerů (atributů, o nichž jsme si říkali, že existují, ale dosud jsme neřekli, k čemu jsou, např. onClick, onSubmit nebo onMouseOver). Nastavování handlerů je jednoduché, stejně jako u ostatních atributů jen přiřadíme požadovaný skript jako hodnotu atributu, čili podobně jako píšeme href="http://www.google.com" zapíšeme onClick="alert('nic');".

Nyní si povězme hlavně o tagu SCRIPT. Jedná se o tag párový, počáteční i koncový tag je vyžadován. Skript tudíž píšeme mezi tagy <SCRIPT> a </SCRIPT>.

Vkládáme-li skript pomocí tagu SCRIPT, máme opět dvě možnosti, jak to provést. Buďto skript napíšeme do zvláštního souboru, na nějž nasměrujeme níže uvedený atribut SRC, nebo skript vložíme přímo mezi tagy <SCRIPT> a </SCRIPT>.

Tagu </script> atributy nevyplňujeme, na tagu <SCRIPT> se vyřádíme trochu více. Můžeme mu nastavovat zejména tyto atributy:

Při použití tagu SCRIPT mějte na paměti, že mezi tagem počátečním a koncovým je text v jiném jazyku, nežli HTML, čili kupříkladu ztrácíte jistotu, že obsah bude case-insensitive, naopak Javascript je case-sensitive! Obdobně bychom měli přestat používat HTML-komentáře a začít používat komentáře povolené gramatikou cílového jazyka.

Existuje určitá výjimka. Z tajemného důvodu někteří lidé píší těsně za tag SCRIPT sekvenci uvádějící HTML-komentář (<!--) a těsně před </script> konec HTML-komentáře (-->). Toto počínání je sice částečně schváleno normou HTML, ovšem pouze jde-li HTML komentář bezprostředně za tagem SCRIPT, konec komentáře ovšem schválení normou HTML nepožívá, každopádně gramatika Javascriptu s tím, že se ve skriptu budou vyskytovat HTML-komentáře, naprosto nepočítá, pro Javascript jde o sekvenci sestávající z operátoru porovnání na nerovnost (<) následovaného operátorem logické negace (!) a predekrementace (--).

Mnozí lidé v dobré víře výše uvedeným jednáním přímo oplývají, aniž zjevně vědí, proč to dělají. Toto jednání mívalo opodstatnění za dávných časů, a to kvůli jistému archaickému prohlížeči, který neměl tag SCRIPT implementovaný a obsah skriptu vypsal. Aby skript nebyl vypsán, byl pro jistotu vnitřek "zabalen" do HTML-komentářů. Tuším, že se jednalo o historickou verzi browseru lynx, ale zdůrazňuji o velmi vykopávkovou verzi. Tato obava z vypsání zdrojových textů Javascriptů u některých autorů stránek (poměrně iracionálně) přežila, bohužel nápadně kontrastruje s hrubým až sprostým chováním některých webmasterů k návštěvníkům používajícím prohlížeč bez skriptování. Obdobně bychom měli přestat používat HTML-komentáře a začít používat komentáře povolené gramatikou cílového jazyka.

Příklad

<SCRIPT type="text/javascript">
/* Komentáře jsou dvou typů. Jeden typ zahajujeme
sekvencí lomeno-hvězdička a ukončujeme obráceně,
tedy hvězdička-lomeno, jako kolem tohoto textu. */
//komentář druhého druhu je jednořádkový a zahajuje
//se dvěma lomítky.

alert('Nic se nedeje...');
alert('10 + 15 = '+(10+15));
</SCRIPT>

Tento skript napřed vypíše výstražné okno s textem "Nic se neděje..." a dalším výstražným oknem oznámí, že 10 + 15 = 25. Řetězce v Javascriptu uzavíráme buď do apostrofů, nebo do uvozovek (je to jedno, ale čím řetězec otevřeme, tím jej musíme uzavřít).

Následující příklad je ukázkou případu, kdy skript napíšeme do jiného souboru, který necháme nahrát ke stránce:

<SCRIPT type="text/javascript" src="soubor.js" language="Javascript1.3">
</SCRIPT>

Jako stránkám s HTML dáváme koncovku html nebo htm (druhá varianta se používala na FAT-filesystému, který umožňoval přípony s nejvýše třemi znaky), souborům s Javascriptem dáváme koncovku js.

Tag NOSCRIPT

Může se stát, že prohlížeč nepodporuje skripty, eventuálně se může jednat o umělecký záměr uživatele znechuceného stálými bezpečnostními dírami v Javascriptu. Aby i uživatel takovéhoto prohlížeče měl ze stránky aspoň nějaký netriviální dojem, mezi tagy <NOSCRIPT> a </NOSCRIPT> dáme HTML-kód, který mají zobrazit prohlížeče, které skripty neinterpretují. V mezích možností se neomezujte na hulvátské sdělení "táhni, nejsou doma" realizované obvykle textem "Vás prohlížeč nepodporuje skripty." Uživatel o tom zpravidla dobře ví a z máločeho má takovou radost, jako z právě uvedené hlášky.

Obecně o Javascriptu

Javascript je jednoduchý skriptovací jazyk, který může zasahovat do vzhledu stránky. Může zejména měnit obsah formulářů, vypisovat text do zdrojového textu stránky, vytvářet dialogová a výstražná okna. Jedná se o jazyk s gramatikou poměrně podobnou jazyku C, jenže není kompilovaný, ale interpretovaný. Oproti kupříkladu Pascalu (Javě, jazyku C a mnoha dalším) není potřeba určovat typ proměnné, mimo to dokonce do jedné proměnné lze přiřazovat hodnoty různých typů. Tento jazyk prakticky ignoruje typovou kontrolu proměnných, oplývá implicitními typovými konverzemi, ne vždy to realizuje tak, jak byste očekávali. Například umožní-li sčítat řetězce, přestává sčítání být (za určitých podmínek) dokonce i komutativní (příklad si ukážeme níže), což v matematice nastává jen v nejzhůvěřilejších modelech.

Javascript lze rozdělit na gramatickou část (popisující, jak program vypadá) a na objektový model. Objektový model říká, které proměnné jsou vestavěné a co dělají. Zatímco gramatika se mezi jednotlivými interprety příliš neliší (je určena normou ECMA-262, pro Javascript verze 2.0 konkrétně verzí 3 uvedené normy), objektový model má každý prohlížeč jiný.

Gramatika Javascriptu

Javascript existuje v několika verzích:

Gramatické záležitosti Javascriptu (stejně jako všech ostatních jazyků) můžeme rozdělit na manipulaci s proměnnými (tedy proměnné a operátory), základní řídící struktury a na definici a volání funkcí:

Manipulace s proměnnými

V Javascriptu je vše objekt. Proměnné (jako naprosto všude jinde) pojmenováváme pomocí identifikátorů.

Základní operátory

Operátorů v Javascriptu existuje mnoho. Uveďme si některé z nich:
+
-
(další jen numerické) odčítání,
*
násobení,
/
dělení,
%
počítání modulo,
&&
(logické) a současně,
||
nebo,
!
negace,
&
(bitové) konjunkce,
|
disjunkce,
<<, >> - bitové posuny.
Sčítání je zleva asociativní, což je důležité zejména směšujeme-li sčítání řetězcové a numerické. Logické operátory mají zvláštní vlastnost, vyhodnocují se zleva doprava a je-li jasný výsledek výpočtu, druhý argument se již nesmí vyhodnotit. Co z tohoto způsobu vyhodnocování plyne? Zejména to, že chceme-li logické operátory aplikovat na výsledky volání funkcí, musíme si být vědomi toho, že snadno může proběhnout jen jedna ze dvou funkcí.

Bitové operátory pohlédnou na argumenty v binárním zápisu a operaci aplikují na každý bit zvlášť. Tedy například bitová konjunkce provede operaci logické konjunkce na každý bit zadaných argumentů.

Další operátory:

=
operátor přiřazení,
==
operátor porovnání (rovnost),
!=
nerovnost,
<, >, <=, >=
menší, větší (resp. rovno),
++, --
inkrementace, dekrementace.
Povšimněte si, že oproti Pascalu je jedno rovnítko operátorem přiřazení. Operátor porovnání na rovnost jsou vždy (zásadně) dvě rovnítka. Oproti Pascalu je tu další odlišnost. Přiřazovací výraz má hodnotu. Jeho hodnotou je hodnota pravé strany (tedy přiřazovaný výraz). Proto kdekoliv můžeme použít operátor porovnání na rovnost, můžeme použít i operátor přiřazení (a implicitní konverze udělají zbytek díla zkázy). Implicitní konverze z číselného typu do typu boolean funguje tak, že nulu zkonvertujeme na logickou lež (eufemicky nepravdu), cokoliv jiného na logickou pravdu. Tedy napíšeme-li if(a=10), jedná se o vyhodnocení vždy splněné podmínky (deset zkonvertujeme na logickou pravdu).

Z Pascalu neznámé jsou operátory inkrementace resp. dekrementace. Jsou to operátory unární a klademe je před nebo za jméno proměnné. Operátor zvýší (resp. sníží o jedna obsah proměnné.

Příklad:

x=++a;
x=a++;
První řádek příkladu zvýší o jedničku hodnotu a a následně tuto (zvýšenou) hodnotu přiřadí do proměnné x. Druhý řádek ukazuje postfixovou verzi operátoru inkrementace. Ta je o maličko méně průhledná, než první. Tento operátor totiž napřed zjistí hodnotu proměnné (kterou vrátí) a až následně obsah proměnné inkrementuje. Tedy bude-li na počátku výpočtu v proměnné a hodnota jedna, druhý řádek zvýší hodnotu v a na dvojku a tuto dvojku přiřadí do x. Ve třetím řádku je v proměnné a hodnota dvě, která bude přiřazena do proměnné x a následně bude obsah proměnné a zvýšen na tři.

Vzhledem k objektovosti Javascriptu je velice důležitý operátor tečky, jehož pomocí přistupujeme k jednotlivým prvkům objektu. Pro první přiblížení si můžeme představit analogii s přístupem do Pascalských struktur, jen oproti Pascalu v objektu existují nejen proměnné (tzv. propriety nebo atributy), ale i funkce (zvané metody). Téměř každý objekt má kupříkladu metodu toString, která vyvolá konverzi do řetězce. Její použití může vypadat takto:

promenna=10;
retezec=promenna.toString();

Řídící struktury

V Javascriptu jsou k dispozici syntaktické konstrukce velmi podobné jiným jazykům. Jedná se zejména o if, které tvoří základní možnost rozhodování v programu. Syntax je takováto:
if(podminka) vyraz
kde vyraz může být buďto jeden příkaz, nebo blok příkazů uzavřený do složených závorek. Povšimněte si úspornosti tohoto zápisu. Kupříkladu oproti Pascalu nepoužíváme klíčové slovo then.

Dále máme k dispozici klíčové slovo else, které nám umožňuje napsat if-větev není-li podmínka splněna. Pokud je vyraz za podmínkou jednoduchý příkaz, před else klademe středník, naopak za případný blok výrazů středník nedáváme.

Příklad

if(a==1)
	funkce();
else	jina_funkce();

if(b==10)
{	prvni_funkce();
	druha_funkce();
}else {	jina_funkce();
	druha_jina_fce();
}

Další základní řídící strukturou je while. Tato struktura umožňuje opakovaně provádět kus kódu, dokud je splněna podmínka.

Příklad

i=0;
while(i<10)
{	alert("jeste nebylo deset");
	i++;
}

Dále je k dispozici řídící struktura for. Tato struktura má syntax shodnou s Javou či jazykem C, leč poměrně odlišnou od Pascalu. Konstrukce vypadá takto: for(inicializační_kód; podmínka;inkrementační_kód)příkazy. Tedy stanovíme, co se má provést při vstupu do for-cyklu, specifikujeme podmínku, cyklus se má opakovat, dokud je splněna, následuje údaj o tom, co se má provést po každé iteraci cyklu (obvykle zvýšit nebo snížit hodnota nějaké proměnné). Pascalskou konstrukci for i:=1 to k do begin prikazy end; můžeme v Javascriptu zapsat takto: for(i=1;i<=k;i++){ prikazy}, tedy stále nic nového pod sluncem (jen Javascriptí for-cyklus je výpočetně mnohem silnější).

Chceme-li vybírat z několika možností, máme k dispozici konstrukci switch. Za klíčové slovo switch uvedeme do závorek výraz, jehož hodnota rozhodne, kterou větem proběhneme. Následují bloky tvaru case vyraz: prikazy..., kde za klíčovým slovem case uvádíme hodnotu při jejímž nabytí řídící proměnnou se má tento blok provést. Ve chvíli, kdy se ukáže, že příslušná hodnota byla nabyta, začíná se kód interpretovat bez ohledu na další case-bloky až do výskytu slova break, tedy v následujícím příkladu při nabytí hodnoty výr2 provedeme i kód pro implicitní případ (ten je uveden klíčovým slovem default):

switch(výraz)
{       case výr1: kód_vykonatelný je-li výraz==výr1...
        break;
        case výr2: kód_vykonatelný je-li výraz==výr2...
        ...
        default: když_neplatí_nic jiného...
}

Funkce a procedury

Javascript nezná pojem procedury. Vše jsou funkce. S ohledem na hromadu typových konverzí lze na procedury pohlížet jako na funkce, které nevracejí hodnotu. Gramatika Javascriptu nám tudíž umožňuje výsledek funkčního volání buďto ignorovat, nebo přiřadit. Chceme-li získat výsledek volání funkce, musíme se ujistit, že funkce opravdu hodnotu vrací.

Funkce voláme podobně jako v jiných programovacích jazycích založených na gramatice jazyka C, tedy tak, že napíšeme jméno funkce následované kulatými závorkami, v nichž jsou argumenty, které chceme funkci předat. Nechceme-li předávat žádné argumenty, necháme závorky prázdné (ale napsat je musíme).

Příklad:

alert('Stiskni knoflik');
document.writeln('kus HTML-textu');
variable.toString();

Příklad:

confirm('Chces pokracovat?');
//tady navratovou hodnotu ignorujeme,
vysl=confirm('A ted doopravdy - chces pokracovat?');
//tady navratovou hodnotu prirazujeme.

Chceme-li definovat novou funkci, postupujeme podobně jako v Pascalu, jen stále místo slova begin píšeme otevírací složenou závorku ({) a místo slova end zavírací (}). Taktéž neurčujeme typ proměnných. Tedy například takto:

function f()
{
	alert('Zavolali jsme funkci f!');
}

function g(a)
{	alert("Zavolali jsme funkci g s argumentem "+a);
}

Za klíčovým slovem return určujeme návratovou hodnotu funkce. Najede-li interpret na slovo return, interpretace funkce končí a vrací se do nadřazené funkce.

Hlavní funkce se nijak zvlášť neoznačuje, sestává prostě z příkazů, které nejsou součástí definice žádných funkcí. Takový kód je proveden okamžitě po nahrání.

Příklad - funkce faktorial:

function faktorial(a)
{       b=1;
        for(c=1;c<=a;c++)b=b*c;
        return b;
}

desfakt=faktorial(10);
//toto probehne hned po nahrani stranky...

Objektový model

Aby bylo možno Javascriptem zasahovat do vzhledu stránky, má každý prohlížeč vestavěnu sadu objektů obsahujících další objekty, atributy a metody. Tyto objekty nám umožňují zasahovat do vzhledu stránky. Každý prohlížeč má strukturu těchto objektů jinou a vpodstatě platí, že čím méně stránku poškodí neexistence některého z objektů, tím lépe. Uveďme si některé tzv. top-level-objekty, tedy objekty na vrchní úrovni:

document
Objekt pohlížející na stránku jako na množinu tagů - obrázků, odkazů, formulářů apod.
navigator
Objekt charakterizující prohlížeč (jméno a verzi).
window
Umožňuje zasahovat přímo do okna prohlížeče (nastavovat nebo aspoň zjišťovat rozměry okna, občas umožňuje i jezdit oknem po ploše.
Math
Objekt obsahující nejrůznější matematické funkce a konstanty (například sinus (sin), absolutní hodnotu (abs), arcus-tangens (atan) a řadu dalších (např. ceil, exp, log, max, min, pow, random, round, sqrt, floor nebo md5).
history
Umožňuje přejít na některou z předchozích (resp. následujících) stránek. Obsahuje zejména metody forward, back a go. První přechází na následující stránku (ekvivalent stisku tlačítka Vpřed), druhý o stránku zpět (ekvivalent tlačítka Back) a třetí očekává údaj o stránce, na kterou má přejít (číslo o kolik se má jít dopředu či dozadu - záporná čísla odkazují ke stránkám minulým, nejtypičtější je history.go(-1);, což udělá totéž, jako history.back();.
frames
Pole rámečků (framů) v současném okně.
Chceme-li prozkoumat objekt, můžeme použít konstrukce for(... in...). Místo první trojtečky udáme jméno proměnné a za slovo inpíšeme jméno objektu. Tato konstrukce funguje jako obyčejný for-cyklus (tedy opakuje tělo cyklu), akorát se cyklus opakuje pro každou položku v objektu. Jméno dotyčné položky je dosazeno do první proměnné.

Příklad:

for(i in document)
	alert(i);

Tento příklad vypíše ve výstražném okně vše, co existuje v objektu document.

Dále u objektů můžete volat metody valueOf a toString. Tyto metody dokonce mohou být vyvolány implicitně při pokusu o konverzi objektu do čísla resp. řetězce.

Javascript obsahuje i funkce pro styk s uživatelem, tedy takové, které buďto něco oznamují, nebo žádají o reakci.

Další pěknou součástí Javascriptu jsou timery. Chceme-li chvíli počkat a pak až na uživatele vybafnout, použijeme funkci setTimeout. Tato funkce přijímá dva argumenty, první obsahuje kód, který se má vykonat, druhý argument je čas v milisekundách, za který chceme kód spustit. Tato funkce vrací řetězec (jméno timeru). Tento řetězec můžeme strčit funkci clearTimeout. O tom, zda timer již proběhl, nebo se nám jej podařilo úspěšně zlikvidovat, nejsme informováni.

Další důležité funkce jsou write a writeln. Jsou v objektu document a umožňují vypisovat přímo do zdrojového kódu stránky. Na které místo stránky se zapíše, záleží na tom, zda byl skript vyvolán při nahrávání stránky (pak vypisuje přímo na místo, na kterém je), v opačném případě vypisuje na konec dokumentu. Obě funkce přijímají řetězcový argument - HTML-kód, který mají vypsat na konec stránky.

Cvičení: Zkoušejte kombinovat příklad na setTimeout a clearTimeout uvedený výše. Vše si též zkoušejte na svých vlastních příkladech.

Některé vestavěné objekty

Objekt document obsahuje zejména tyto atributy resp. metody:
alinkColor
Údaj o barvě aktivního odkazu,
linkColor
barva odkazů,
vlinkColor
barva navštívených odkazů,
forms
pole formulářů v dokumentu (obvykle jedno nebo nulaprvkové),
location
objekt popisující URI současné stránky,
title
objekt popisující titulek stránky,
referer
kdo nás poslal?
V objektu frames máme pole rámečků. V každém rámečku je zejména:
location
údaje o URI současné stránky,
frames
rámečky v současném rámečku,
parent
objekt rodičovského rámečku,
top
nejvyšší frame (dělící celé okno),
close
metoda, která ukončí současný frame.
V každém formuláři máme hlavně toto:
action
URI, kam se má formulář odeslat,
elements
pole prvků v dotyčném formuláři,
submit
metoda, která odešle formulář,
reset
metoda, která formulář vymaže.
Každý prvek formuláře může být mimo jiné zavolán jménem, které má přidělené, tedy třeba místo document.forms[0].elements[0] můžeme psát například document.forms[0].jmeno...

V každém elementu formuláře najdeme zejména atributy name a value. První určuje jméno prvku, druhý jeho hodnotu. Prvky různé od radio a checkbox mají třeba atributy checked a defaultChecked, radiobutton je opět pole jednotlivých voleb... select má atributy options, index, selected, selectedIndex a text.

Ovladače událostí

Chceme-li vyrobit ovladač události, přiřadíme prostě kus Javascriptu do příslušného atributu například takto: onMouseOver="alert('prijela mys');".

Některé handlery mají zvláštní moc. Například vrátí-li ovladač události onSubmit logickou lež (false), odeslání se zmaří. Toto je velmi užitečné chceme-li experimentovat s formuláři zvláště náchylnými na vyplnění. Zjistí-li Javascript, že je špatně vyplněno, je nesmysl zbytečně obtěžovat server pokaženým formulářem.

Příklad:

<SCRIPT type="text/javascript">
function check_form()
{	if(document.forms[0].jmeno.value=="")
	{	alert('Jmeno musi byt vyplneno!');
		return false;
	}
}
</SCRIPT>
<form action="skript.php" onSubmit="return check_form();">
Zadej jmeno: <input type="text" name="jmeno"><br>
<input type="submit" value="odeslat">
</form>
se zobrazí asi takto:
Zadej jmeno:
Možné handlery jsou tyto: Samozřejmě ne každý element disponuje všemi těmito ovladači událostí (například onSubmit má smysl pouze u formuláře). Nejlepší seznam co k čemu patří najdete v normě HTML.

Vlastní objekty vyrobené pomocí Javascriptu

Jelikož Javascript je objektový jazyk, je přirozené, že si můžeme vyrobit vlastní objekty. K tomuto používáme operátory new a delete. Za operátor new klademe volání funkce (tedy například new funkce();). Výsledkem je objekt obsahující lokální proměnné funkce uvedené za operátorem new. K čemu může být tento nástroj dobrý? Kupříkladu jako ekvivalent typu record z Pascalu, tedy k udržování několika hodnot souvisejících s jedním jevem.

Uveďme si příklad telefonního seznamu. V tom udržujeme jméno, příjmení a telefonní číslo. Chceme-li přidat do seznamu člověka, použijeme operátor new takto:

Příklad

function clovik(jm,prij,cis)
{	jmeno=jm;
	prijmeni=prij;
	telefon=cis;
}

novy_clovek=new clovik("Kamil","Novak","776 112 777");

V příkladu jsme vytvořili objekt jménem novy_clovek mající vlastnosti jmeno, prijmeni a telefon. Chceme-li nyní kupříkladu změnit číslo člověku z minulého příkladu, přistoupíme do objektu jej popisujícího pomocí operátoru tečky.

Příklad

novy_clovek.telefon='604 111 111';

Chceme-li objekt zrušit, použijeme operátor delete. Za klíčové slovo delete klademe jméno objektu, který chceme zrušit (tedy například delete novy_clovek;). Důležitou vlastností objektů je, že operátorem new vyrobíme jen jednu instanci, tedy pokud bychom objekt přiřadili do další proměnné, jedná se stále o jeden a tentýž objekt. Tedy například provedeme-li mezi vytvořením a zrušením objektu novy_clovek přiřazení roztomily_clovek=novy_clovek;, po operaci delete novy_clovek; přestává existovat i obsah proměnné roztomily_clovek!

Vytvoříme-li v každém objektu odkaz na objekt předchozí (a případně i následující), můžeme po těchto odkazech přecházet a takové struktuře říkáme spojový seznam. Ukazujeme příklad telefonního seznamu, který svou složitostí poněkud převyšuje ambice tohoto materiálu, ale je jednou z mála rychle vysvětlitelných aplikací objektů (pochopitelně by šlo postupovat třeba přes asociativní pole...).

Pole

Pole v Javascriptu slouží například k pořádání více dat. Máme-li sadu měření, můžeme si jednotlivé hodnoty uložit do pole. Pole vytváříme jako další objekt pomocí operátoru new, že objekt má být pole řekneme takto: pole=new Array();. Array je vestavěná metoda (funkce), která vytvoří objekt typu pole (čili operátorem new vytváříme nejen své vlastní objekty, jak by si člověk mohl myslet z minulého oddílu. Do pole přistupujeme pomocí operátoru hranatých závorek (jako v mnoha ostatních jazycích). Array je silně multifunkční konstruktor a tvoří pole mnoha různými způsoby. Zadáme-li jako argument jedno celé číslo, má se za to, že určujeme délku pole. Zadáme-li argumentů více, nebo je-li argument něco jiného, než kladné celé číslo, má se za to, že pole inicializujeme. Každé pole má atribut length, který určuje délku pole. Nastavíme-li délku pole kratší, než byla dosud, má se za to, že chceme pole zinicializovat. První prvek pole má index nula!

Příklad

a = new Array(); //Prázdné pole (délky nula)
b = new Array('ahoj'); // Pole délky jedna, a[0] je 'ahoj'
c = new Array(5); // Pole délky 5 plné nedefinovaných prvků.
d = new Array('1','1','2','3','1');
// Pole delky pet obsahujici ruzna cisla 1 -- 3.
// Patrne popisuje neci studijni vysledky :-)

Javascript dále umí tzv. asociativní pole. Asociativní pole je také pole (tedy vytvořené pomocí new Array(...), ale jeho prvky nejsou indexovány čísly, nýbrž řetězci. Místo dlouhého vysvětlování přistupme k názornému příkladu:

TWS = new Array();
TWS['Novak_Jan']='Zapocteno';
TWS['Houska_Kamil']='Zapocteno';
TWS['Mameluk_David']='Nezapocteno';

alert('Novák má z TWS '+TWS['Novak_Jan']);
Příklad ukazuje syntax i s aplikací, tedy možné výsledky studentů nejmenovaného předmětu v poli indexovaném přímo jmény dotyčných.

Příklady

Výměna obrázku:
Strašidelný vyučující:
Strašidelný vyučující v akci! Lloydova patnáctka,

Test celočíselnosti vstupu:

Zadej číslo:

Zaklikávání ve formulářích:

VzorObraz
Jeden
Druhý

Cvičení: Hra Pexeso se hraje tak, že rozmístíme 2k lístků s čísly 1, 2,..., k (každá hodnota se vyskytuje právě dvakrát). Hráč otočí dva lístky. Pokud je na obou lístcích totéž číslo, hráč lístky bere a hraje znovu. Pokud se čísla neshodují, lístky se otočí zpátky a hraje protihráč. Implementujte jednoduché pexeso v Javascriptu. Ve skutečnosti se místo čísel používají obrázky. Pokud chcete, můžete je použít též.

AJAX

AJAX je zkratka Asynchronous Javascript and XML. Jedná se o možnost pomocí Javascriptu zasílat data na server bez reloadu současné stránky. Je zvláštní tím, že se o jeho podporu stará pouze klient (což je výhodné v tom, že není potřeba nic zásadního zprovozňovat, nevýhodné je to ovšem proto, že ne všechny prohlížeče AJAX podporují, případně jej nepodporují stejným způsobem.

Pokud chceme AJAX využít, vytvoříme si speciální objekt, kterému budeme volat vybrané metody, případně číst a nastavovat atributy anebo nastavovat handlery událostí. Třída, jejíž instanci (objekt) budeme tvořit, se jmenuje XMLHttpRequest, ovšem na Internet Exploreru verze 5 a 6 se tvoří konstruktorem ActiveXObject("Microsoft.XMLHTTP"). Vytvoření příslušného objektu by tedy mohlo vypadat xmlhttp=new XMLHttpRequest();

Pokud už máme instanci této třídy vytvořenu, můžeme použít mimo jiné následující metody a atributy:

open(metoda,cil,asynchronni)
Oznámíme které stránce (skriptu) se mají data předat, jakou metodou a zda má být spojení synchronní nebo asynchronní (synchronní znamená, že se běh Javascriptu zastaví do chvíle, kdy přijde odpověď). Přesnější smysl argumentů je:
send()
Tato metoda je výkonná - odešle nastavený požadavek na server.
setRequestHeader(udaj,hodnota)
Přidá do HTTP-hlavičky zadaný údaj. Můžeme (musíme) použít například u metody POST k nastavení typu odesílaných dat: a.setRequestHeader("Content-type:","application/x-www-form-urlencoded");
onreadystatechange
Ovladač změny stavu. Do něj přiřadíme funkci, která se má zavolat, kdykoliv se změní stav odpovědi. Tento ovladač může reflektovat příslušné změny (vypisovat do stránky).
responseText
Atribut obsahující odpověď serveru v podobě textu.
responseXML
Odpověď od serveru v XML.
status
Atribut oznamující stav spojení (třímístný číselný kód).
readyState
Atribut hlásící stav zpracování našeho requestu (nabývá hodnot 0 - 4, hodnoty znamenají (v tomto pořadí): request not initialized, connection established, request received, processing request, finished). Data zaslaná nám serverem tedy můžeme zpracovat, pokud je tento readyState roven čtyřem.

Příklad:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<title>Pokus s Ajaxem</title>
<script type="text/javascript">
function delej()
{	if (window.XMLHttpRequest)
		// code for IE7+, Firefox, Chrome, Opera, Safari
		xmlhttp=new XMLHttpRequest();
	else	// code for IE6, IE5
		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	xmlhttp.onreadystatechange=function()
	{	if (xmlhttp.readyState==4)
    			document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
	}
	xmlhttp.open("GET","ajax_info2.txt",true);
	xmlhttp.send();
}
</script>
<button type="button" onclick="delej()">Jedeme!</button>
<div id="myDiv">
Tady se neco stane!
</div>
V příkladu vidíme tlačítko (tag button) po jehož stisknutí se zavolá funkce delej. Prvních pět (efektivních) řádků (tedy mimo hlavičku funkce) vytváříme příslušný objekt (který pošle request na server a oznámí nám příchod odpovědi). Dále (další čtyři řádky) nastavujeme ovladač (co se má odehrát při odpovědi ze serveru - přesněji při změně stavu vyřizování požadavku). Všimněte si, že do onreadystatechange přiřazujeme definici nepojmenované funkce (mezi slovem function a formálními argumenty chybí jméno funkce). Tato funkce zjistí, zda je odpovídání ve stavu 4 (tedy zda je odpovězeno). Pokud ano, zapíše do divu (definovaného ve stránce za tlačítkem) text, který nám přišel (nastaví mu atribut innerHTML). Předposlední zajímavý řádek zdrojáku říká, kam se má request poslat (stránce jménem ajax_info2.txt ve stejném adresáři, jako jsme my), že data máme posílat metodou GET a že komunikace bude asynchronní (tedy že skript nemá čekat na odpověď). Poslední řádek pak celý proces spustí (pošle dotaz na server - a až je tento ve stavu zpracování 4, ovladač změny stavu zpracování vypíše odpověď do DIVu).

Cvičení: Vybavte souvislý příklad Kafomat skriptem využívajícím AJAX ke zjišťování dostupnosti jednotlivých druhů káv (do objednávacího formuláře tento indikátor vhodně zapracujte) a taktéž ceny jednotlivých nápojů načítejte pomocí AJAXe (jelikož se mohou každou chvíli měnit podle poptávky jako například ceny letenek).