V dalším pokračování našeho seriálu o JavaScriptu se dostáváme na funkce, jejich zápis a využití v praxi. Začneme i dynamické HTML a především objektové programování.
FUNKCE
Každý program má nějakou strukturu. Kdy bude jaký příkaz proveden záleží na jeho umístění v daném programu. Někdy však bývá lepší nadefinovat si posloupnot příkazů jako funkci, čímž se zjednoduší a zkrátí např. opakované zadávání příkazů či bloků programu. Částečně jsme se již s funkcemi setkali - u objektů string, Math a Date při práci s jejich metodami. Metoda je v podstatě jen jiný název pro funkci. Objekt je soubor pojmenovaných hodnot - vlastností a funkcí, které uživateli umožňují s těmito objekty pracovat. Objekt Math a jeho metody jsou vlastně předdefinované funkce, které má JavaScript vestavěny, stejně jako řadu dalších (metody pro práci s řetězci, datumem atp.) JavaScript však samozřejmě umožňuje také naprogramovat si funkce vlastní, které pak můžete ve svém hlavním programu (dokumentu) volně vyvolávat a používat. Funkce se používají zejména pro opakované činnosti a obsluhu různých událostí, jež mohou nastat.
Malý příklad funkce:
function vypis(text) {
document.write("<b>", text, "</b>");}
Názvy funkcí píšu pokud možno česky, abyste mohli lépe rozlišit syntaxi. Pokud pak někde ve stránce použijete příkaz jako:
vypis("Atari forever!");
bude text v závorkách vždy vypsán tučně, neboť se vlastně vyvolá funkce "vypis". Z toho je vidět, že funkcím lze předávat i data, která mají zpracovat. Tato data jsou předávána jako argumenty volané funkce, v tomto případě to byl libovolný text. Ten se uloží do vlastní funkce do proměnné "text", se kterou se pak dále pracuje. Jako argument může sloužit jakákoliv proměnná (objekt, pole, ...)
1. Zápis, definice a volání funkce
Obecný zápis funkcí:
function nazevfunkce ([a1 [,a2 [..., an]]])
{
tělo funkce
}
Možná to nevypadá nejjednodušeji, ale není to těžké. Jednotlivé části mají tento význam:
jmenofunkce = téměř libovolný název funkce, která je tímto definována
a1 ... an = seznam libovolného počtu argumentů funkce, které jsou vždy odděleny čárkami. Bude-li funkce volána, budou těmto argumentům přiřazeny hodnoty specifikované ve výrazu volání funkce. V našem příkladu výše to byla pouze jedna proměnná "text".
tělo funkce = blok příkazů, které mají být při volání funkce vykonány. Je nutné (jinak řečeno povinné!) u funkcí používat složené závorky, kterými se ohraničuje tělo funkce, a to i v případě, že je v tělě obsažen pouze jediný příkaz.
Příkazy tvořící tělo funkce nebudou provedeny hned, ale právě až při volání dané funkce, to je myslím jasné.
Toto byl první typ funkcí, funkce provádějící nějakou operaci. Druhou variantou jsou funkce, které předáte nějaké argumenty, funkce je zpracuje a zpět vrátí výsledek, ať už je jakéhokoliv typu. Skvělým příkladem je např. funkce kosinus:
x=Math.cos(1.6);
Návratovou hodnotou funkce Math.cos je kosinus úhlu 1.6, který bude přiřazen do proměnné "x". Příkazem, který zajistí, aby funkce vrátila nějaký výsledek, jenž bude dále zpracován, je "return". Jeho použití si ukážeme jak jinak než na příkladu. Porovnáme dvě hodnoty a určíme tu menší z nich. Pokud bude menší první hodnota, nechť program vrátí jedničku, pokud druhá nechť vrátí dvojku a budou-li snad stejné, vrátí nulu:
function porovnani(a,b) {
if (a < b) return 1;
if (a > b) return 2;
else return 0; }
A je to. Jakmile byla funkce takto jednou nadefinována, může být kdykoliv vyvolána a provedena. Funkci dle tohoto příkladu vyvoláme nejjednodušeji takto:
porovnani(x,y);
Jelikož však zřejmě budeme chtít s výsledkem porovnávání dále pracovat, musíme toto volání funkce přiřadit nějaké proměnné (anebo třeba vypsat na obrazovku):
vysledek=porovnani(4,15);
document.write(porovnani(8,3));
Kdykoliv zavoláme funkci "porovnani" a zadáme jí požadované argumenty, provede vyhodnocení a vrátí buď 1, 2, nebo 0 dle výsledku. Příkaz "return" tedy nejen že vrací nějakou hodnotu, ale vždy také přeruší běh funkce. Je to myslím dost jasné z příkladu výše; pracuje podobně jako v jiných programovacích jazycích.
Když vyvoláte funci, každý z výrazů specifikovaných v závorkách je vyhodnocen a výsledná hodnota je použita jako argument nebo parametr dané funkce. Tyto hodnoty jsou přiřazeny proměnným, pojmenovaným u definic funkce, a funkce operuje se svými parametry tak, že na ně odkazuje názvem. Tyto parametrické proměnné jsou však definovány pouze po dobu provádění dané funkce a při ukončení zpracovávané funkce jsou zrušeny.
Obecný zápis příkazu return je:
return [výraz];
Příkaz return však může mít i něco složitější syntaxi, např.:
function mocnina(x) {return x*x;}
Zde tedy přímo ve svém těle již spočítá nějaký (i daleko složitější než je uveden zde) matematický výraz.
Return může být použit také bez výrazu k jednoduchému ukončení provádění funkce bez vrácené hodnoty. Jestliže funkce provede prázdný příkaz return (nebo pokud jej nikdy neprovede, čili všechny výrazy ve svém těle vrátí standardní cestou), bude hodnota výrazu volající funkci nedefinovaná.
Funkce "return" může obsahovat prakticky jakýkoliv výraz, který lze vyhodnotit tak, aby byla určena nějaká návratová hodnota. Následuje příklad funkce výpočtu vzdálenosti mezi dvěma body, tuto vzdálenost pak funkce vrátí:
function vzdalenost(x1, y1, x2, y2)
{
var dx = (x2 - x1);
var dy = (y2 - y1);
return Math.sqrt(dx*dx + dy*dy);
}
2. Opakované volání funkce
Funkce může volat i sama sebe (opakované neboli rekurzivní volání funkce). Pěkný příklad nám poskytuje funkce pro výpočet faktoriálu zadaného čísla:
function faktorial(x)
{
if (x <=1)
return 1;
else
return x* faktorial(x-1);
}
Jak tato funkce pracuje. Nejdříve je jí z hlavního programu předána hodnota, z níž se más počítat faktoriál. Co je to faktoriál doufám všichni vědí, jinak by to s pochopením funkce nemuselo být valné. Funkce otestuje hodnotu proměnné a pokud se rovná jedničce, je faktoriálem číslo 1 a funkce tudíž vrátí hodnotu 1. Zde pro usnadnění funkce vrátí jedničku i když bude číslo menší než jedna, což je diskutabilní. Pokud bude číslo větší než jedna, bude vynásobeno hodnotou funkce faktoriál s novým argumentem, menším o jedničku, což je způsob výpočtu faktoriálu. Zde tedy funkce volá sebe samu, provádí rekurzivní volání. To se provede tolikrát, jakou hodnotu má původní argument snížený o jedničku. Má-li např. hodnotu 6, provede se pětkrát.
Je to doufám dost jasné, zvolil jsem jednodušší ukázku, ze které se to dá pochopit i bez širšího vysvětlování.
Upozornění
JavaScript je netypový jazyk, neočekává tudíž funkce ani specifikace datových typů pro argumenty funkcí. JavaScript při provádění funkce ani nekontroluje, zda jste předali typ dat, který funkce očekává. Nekontroluje dokonce ani to, zda jste předali správný počet argumentů; pokud jich bude více, hodnoty navíc budou jednoduše ignorovány, pokud méně, pak některý z parametrů dostane nedefinovanou hodnotu, což většinou způsobí, že se funkce nebude chovat tak, jak by měla. Proto obzvláště při delších a složitějších funkcích kontrolujte co píšete.
S dalšími funkcemi se setkáme již přímo v ukázkách některých programů.
OBJEKTOVÉ PROGRAMOVÁNÍ
DHTML, neboli dynamické HTML je další úrovní tvorby www stránek. Na rozdíl od klasického HTML není statické a umožňuje měnit stránku i po jejím načtení do prohlížeče, a to v závislosti na tom, co právě uživatel dělá nebo naopak nedělá. Dosahujeme tak např. změn stylů písma při přejetí kurzorem myši nebo při události, měnící se obrázky při najetí kurzorem myši atp. DHTML tak umožňuje (prostřednictvím skriptů) ovládat téměř každý prvek ve stránce.
Základní prvky, kterými lze chování stránky ovlivňovat, je objektový model prohlížeče, události prohlížeče a styly.
1. Objekty prohlížeče
JavaScript umožňuje ovládat samotný prohlížeč prostřednictví jeho objektů. Tyto objekty vám vkládají do rukou velice silný vývojový nástroj. Pomocí nich lze dosáhnout téměř všeho, na co si vzpomenete.
S některými objekty jsme se seznámi již dříve, zde se naučíme další, ukážeme si všechny blíže a zmíníme se o konkrétnějším využití.
Co je vlastně objekt? Jedná se o soubor pojmenovaných dat a funkcí, ne které je odkazováno jako na vlastnosti tohoto objektu. Pokud vám to zní zmateně, pochopíte to při příkladech.
Na vlastnost objektu se obecně odkazuje takto:
objekt.vlastnost
Dobrým příkladem zde může být např. výška a šířka obrázku:
image.height
image.width
Vlastnosti objektů se v mnoha ohledech chovají jako proměnné JavaScriptu a mohou obsahovat jakýkoliv typ dat, včetně polí, funkcí i jiných objektů.
Kromě vlastností má objekt také definovány určité funkce, které s tímto objektem nějakým způsobem pracují a mohou k tomu využívat i jeho vlastností. Taková funkce se nazývá >metoda< a má svoje jméno a argumenty, které jsou jí předávány.
Metoda se obecně používá takto:
objekt.metoda()
Jako příklad využijme již známou metodu "write" objektu "document":
document.write("Tento text bude vypsán");
Objekty prohlížeče jsou propojeny navzájem do objektového modelu. To je něco jako strom popisující, jakým způsobem jsou tyto objekty spojeny dohromady. Začíná kmenem, kde stojí objekt >WINDOW<, a odkazuje na své jednotlivé větve - >FRAMES<, >DOCUMENT< a další. U objektového modelu jsou navíc objekty programovatelné - můžete sami nastavovat jejich vlastnosti, volat konkrétní metody nebo ovládat je událostními funkcemi.
V každém objektovém modelu obvykle bývá jeden objekt na nejvyšší úrovni. V prohlížeči je tímto objektem okno prohlížeče, neboli objekt >WINDOW<. Proto se na objektový model prohlížeče lze dívat jako na objekt okna prohlížeče, v němž jsou obsaženy všechny ostatní objekty, vlastnosti a metody.
Objekt >window< zastřešuje tyto hlavní objekty:
- history - historie navštívených stránek
- navigator - informace o použitém prohlížeči
- location - aktuální adresa www stránky
- frames - rámy, jež jsou obsaženy v aktuálním okně
- document - vlastní obsah stránky aktuálního okna
- event - informace o aktuální události.
1. Objekt WINDOW
Objekt >window< je hlavním a nadřazeným objektem všech objektů ostatních, reprezentuje okno prohlížeče, nejvyšší strukturu. Díky tomu, že je objektem hlavním, není třeba jej implicitně uvádět. Prohlížeč ví, že všechny objekty, vlastnosti a metody jsou jeho součástí. Viz příklad:
Kompletní zápis pro vyvolání metody "alert", je:
window.alert("Text v alert boxu.");
Jelikož již víme a ví to i prohlížeč, že window je hlavním objektem a alert jeho metodou, stačí psát:
alert("Text v alert boxu.");
A stejné je to i ostatními vlastnostmi a metody objektu window, my již známe např. "document":
window.document.write("Text");
je jen kompletní syntaxe již známého:
document.write("Text");
Vlastností, objektů a různých metod má objekt >window< moc a moc, já zde zmíním ty nejdůležitější a nejčastější:
Základní vlastnosti objektu window:
- document - odkaz na objekt "document", jenž je součástí aktuálního okna
- frames[] - pole rámů, které obsahuje aktuální stránka
- history - odkaz na objekt "history" pro dané okno, tzn. seznam navštívených stránek z tohoto okna
- length - počet prvků v poli "frames[]", totéž jako "frames.length", uchovává počet rámů v aktuálním okně
- location - odkaz na objekt "location" pro dané okno, uchovává informace o aktuálním URL stránky
- Math - odkaz na objekt, který uchovává konstanty a počítá matematické funkce
- name - název aktuálního okna
- navigator - odkaz na objekt "navigator", jenž uchovává informace o prohlížeči
- status - řetězec, v němž je obsažen aktuální obsah stavového řádku
- window - odkaz na okno samotné.
Základní metody objektu window:
- alert() - zobrazí alert box
- clearTimeout() - ruší nevyřízené operace časovače
- close() - zavře aktuální okno
- confirm() - v dialogu/alertu se pokládá dotaz typu "Ano/Ne"
- open() - vytváří a otevírá nové okno
- prompt() - v dialogu/alertu očekává nějaký vstup
- setTimeout() - po uplynutí určeného času provede zadaný kód.
1.1 Metoda ALERT
Metoda alert je velmi jednoduchá a slouží k vypsání uživatelem definované zprávy v dialogovém okénku (přesněji v alert boxu). Alert box obsahuje pouze tlačítko OK a jako ikonu pouze vykřičník; na to je třeba pamatovat zejména kvůli druhu vypsaných zpráv, aby se na ně hodil vykřičník a "OK", většinou tedy nějaká upozornění apod.
Obecná syntaxe:
window.alert("Text v okénku.");
Samozřejmě "window" lze v zápisu vynechat, to už víme. Pro přechod na nový řádek se používá "/n", proto chcete-li zprávu přesně rozdělit do více řádků, musíte použít právě tento oddělovač, jinak bude rozdělena dle aktuálního fontu v závislosti na použité platformě.
1.2. Metoda PROMPT
Tato metoda se používá pro získání nějakého údaje od uživatele pomocí dialogového okénka. "promtp" vypíše co se po uživateli chce a navíc i textové políčko, kde se očekává odpověď od uživatele.
Syntaxe:
window.prompt(text)
window.prompt(text, retezec);
Samozřejmě lze i bez "window". "text" je jednoduchý text, který se v dialogu zobrazí jako požadavek na vstup, "retezec" pak specifikuje implicitní text, který bude zobrazen ještě předtím, než uživatel něco zadá, specifikován ale být nemusí.
prompt("Cekam na vstup", "");
Výstupem této metody ja řetězec, který specifikuje uživatelem vepsaný text, nebo "null", pokud uživatel odkliknul tlačítko "Storno". Tento výstup se pak přiřadí do nějaké proměnné, aby se s ním dalo pracovat:
vstup = window.prompt("Cekam na vstup", "");
Zpráva této metody může být pouze jednořádková a dialog samotný nelze nijak zvětšit ani změnšit.
1.3. Metoda CONFIRM
Tato metoda se používá pokud má uživatel odpovídat pouze Ano/Ne. V takovém případě se zobrazí dialog s tlačítky "OK" reprezentující pod Woknama "Ano", a "Storno" značící "Ne". Syntaxe:
window.confirm("Máš rád Narsil?");
"window" opět není nutné. Klikne-li uživatel na "OK", vrátí tato metoda "true", jinak vrátí "false". Pro přečtení této hodnoty je vhodné použít nějakou proměnnou, jak to bylo ukázáno výše a na základě její hodnoty pak odpověď vyhodnotit (třeba podmínkou). I zde lze použít pro odřádkování "/n", podobně jako u metody >alert<.
1.4. Metody OPEN a CLOSE
V JavaScriptu můžeme pomocí objektu >window< a metod "open" a "close" otevřít resp. uzavřít nějaké okno. Začněme s metodou "open". Syntaxe:
window.open(adresa, jmeno, [vlastnosti]);
"adresa" specifikuje URL dokumentu, jenž se v okně otevře. Pokud bude předán prázdný řetězec, otevře se prázdné okno. "jmeno" je název okna, jenž se používá např. u příkazů <target>, <a> nebo <form>. Parametr "vlastnosti" určuje, jaké vlastnosti bude nově otevřené okno mít. Je volitelný a reprezentuje jej řetězec obsahující čárkami oddělené jednotlivé vlastnosti:
open("soubor.html","nazev","width=640,height=240, toolbar=no,directories=no,status=yes,scrollbars=yes, resize=no,menubar=no");
Tento příkaz otevře okno o velikosti 640*240 bodů do něhož načte soubor "soubor.html". Zakáže použití panelu nástrojů (toolbar), odkazů (directories), hlavního panelu (menubar) a také zvětšit či zmenšit okno. Dovolí zobrazit stavový řýdek (status) a posuvníky (scrollbars). Pokud nějaký parametr vypustíte, bere se jako "no".
Okno lze samozřejmě i zavřít a to příkazem
window.close();
jenž zavře aktuální okno. Prohlížeč většinou zobrazí zprávu, že se stránka pokouší okno zavřít a vy to můžete potvrdit nebo zrušit.
1.5. Metody SETTIMEOUT a CLEARTIMEOUT
Metoda "setTimeout" je časovačem událostí. Odkládá provedení příkazů JavaScriptu specifikvoaných v řetězci "kód" (viz dále), kterých se to týká, o zpoždění dané argumentem "čas" v milisekundách. Poté co specifikovaný počet milisekund uplyne, jsou příkazy provedeny, ovšem pouze jednou. Pro opakované provádění musí řetězec "kód" obsahovat opětovné volání metody "setTimeout", aby se opět nastavil čas, který má uplynout.
Obecná syntaxe:
window.setTimeout(kód, čas);
Ukažme si to na příkladu časového programu, tedy programu, jenž má za úkol zjistit aktuální čas a poté jej každou sekundu obnovovat, tzn. efekt jdoucích hodin:
function hodiny() {
today = new Date();
hours = today.getHours();
minutes = today.getMinutes();
seconds = today.getSeconds();
timeValue = hours; timeValue += ((minutes < 10) ? ":0" : ":") + minutes;
timeValue += ((seconds < 10) ? ":0" : ":") + seconds;
document.clock.time.value = timeValue;
window.setTimeout("hodiny()",1000); }
Jakmile tuto funkci jednou spustíte, např. příkazem
<BODY ONLOAD="hodiny()">
zjistí aktuální čas, zformátuje jej do čitelné podoby (to jsou 6 až 8 řádek) a umístí jej do políčka "clock" jenž se jmenuje "time". Zde už lze použít i jiné umístění, téměř kamkoliv. Poslední řádka udává, že funkce bude spuštěna znovu a znovu každou sekundu. Její vyvolání zajistí příkaz ONLOAD, se kterým se blíže seznámíme příště, a to ihned po načtení stránky, neboť je součástí těla <BODY>.
Jiným příkladem může být pulzující text, tzn. text pravidelně za určitý časový interval měnící svoje písmo, barvu, velikost atp.:
var cerne=true;
function Pulse() {
if (cerne==true) {
document.all.puls.style.color="fuchsia";
cerne=false; }
else {document.all.puls.style.color="black"; cerne=true }
setTimeout("Pulse()", 2000);}
Pak stačí opět umístit příkaz <BODY ONLOAD="setTimeout('Pulse()',2000)"> a pak jakýkoliv text v dokumentu označený příkazem
<span id="puls"> ... </span>
bude měnit ve dvousekundových intervalech barvu z černé na fialovou a naopak. Podívejte se na řádku začínající "else" - "document" říká že se daná operace týká dokumentu, "all" znamená celého, "puls" je název použitý při vyvolání příkazy jako <span> nebo <p>, "style" značí změnu stylu a "color" že půjde o změnu barvy.
Metoda "setTimeout" má i svoji návratovou hodnotu, která se používá pro zrušení časového provední aktuální operace metodou "clearTimeout". Opět příklad:
Pokud kdekoliv v programu uvedeme:
provest = window.setTimeout(kód, čas);
získá proměnná "provest" hodnotu právě nastaveného opožděného provádění určitých příkazů. Pokud kdykoliv před provedením těchto příkazů narazí JavaScript na řádek:
window.clearTimeout(provest);
bude toto opožděné provádění zrušeno. Obeně tedy metoda "clearTimeout" ruší provádění kódu, který byl odložen metodou "setTimeout". Využívá se např. pro zobrazování aktuální času, pulzující text apod.
To je pro tento díl všechno, přístě budeme pokračovat dalšími objekty a dalšími příklady a také událostmi a prespříště náš seriál zakončíme.
Již dnes vás ale mohu odkázat na stránky "www.interval.cz", kde se vytváření www stránek včetně JavaScriptu, kaskádových stylů a dalším věcem, věnují celé články s ukázkami.
Neznámý vojín