JavaScript se v průběhu let rozvíjel a začleňoval do sebe další technologie. Nejdůležitější z nich (DOM, OOP, regEx, AJAX, canvas) si nyní představíme.
Začátky a DOM
Velmi brzy po rozjezdu WWW se objevila potřeba technologií, které by webovým stránkám umožnily interakci s uživateli. První inovací v tomto směru bylo automatické generování stránek prostřednictvím rozhraní CGI (Common Gateway Interface). Jednou z hlavních nevýhod tohoto řešení byla pomalá odezva CGI skriptů, proto se začalo přemýšlet, jak by se daly alespoň některé úlohy přesunout ze serveru na klienta, což by znamenalo značné urychlení. Kýžená spása se dostavila ve dvou variantách. Tou první byl nový jazyk Java, představený firmou Sun Microsystems, který umožňoval psaní Java apletů – prográmků integrovaných přímo do stránky. Tou druhou byl v roce 1996 JavaScript.
Možnosti JavaScriptu nebyly v původní implementaci od firmy Netscape závratně rozsáhlé, to se však změnilo v roce 1997 s nástupem IE 4. V novém prohlížeči od Microsoftu již bylo možno přistupovat ke každému objektu na stránce a měnit jej (tzv. DHTML). Konkurenční Netscape brzy vyvinul podobné API. Jelikož podobné neznamená stejné, museli programátoři vytvářet skripty složitěji, nebo je psát jen pro jeden z prohlížečů. Situaci vyřešilo až W3C, které vypracovalo DOM (Document Object Model) a zavedlo jej jako standard. Specifikovalo v něm rozhraní pro přístup k objektům dokumentu a událostem. Jen to samozřejmě nestačí, a tak je DOM doplňován dalšími API, z nichž většinu dokumentuje připravovaná specifikace HTML 5 (mezi nejvýznamnější z nich patří např. drag and drop API, Canvas nebo API pro přehrávání multimediálních objektů.
O DOM a DHTML na Interval.cz
- Programujeme DHTML aplikace – dokument (2002)
- Programujeme DHTML aplikace – obsah (2002)
- Programujeme DHTML aplikace – efekty CSS (2002)
- Programujeme DHTML aplikace – interakce s uživatelem (2002)
Objektově orientované programování
Při vytváření větších aplikací, na kterých se podílí více programátorů, je OOP nevyhnutelnou nutností, proto nesmí chybět ani v JavaScriptu. Nejprve si ukážeme, jakými způsoby se v JavaScriptu objekty vytvářejí.
var automobil = new Object(); automobil.barva = "modrá"; automobil.rok_vyroby = 2003; automobil.nastartuj = function() { this.zvuk = "vrumm"; this.stav = "nastartováno"; }
V prvním příkladu jsme pomocí operátoru new
definovali objekt automobil
, kterému jsme vzápětí přiřadili pár vlastností a jednu metodu.
var automobil = { barva : "modrá", rok_vyroby : 2003, nastartuj : function() {alert("Vrumm")} }
Ve druhém příkladu jsme pro vytvoření objektu automobil
využili objektový literál. Výsledek je ovšem v podstatě stejný, liší se jen metoda nastartuj()
, poněvadž v každém příkladu obsahuje jiné příkazy.
Na předchozích dvou příkladech jsme si představili dva poměrně jednoduché způsoby vytváření objektů. Ani jeden z nich se však příliš nehodí v situaci, kdy je potřeba vytvářet více objektů stejné povahy – tedy se stejnými vlastnostmi a metodami. Proto je tu ještě jiné řešení – konstruktor. Na dalším příkladu si ukážeme, jak takový objektový konstruktor vypadá. Zdánlivě jako běžná funkce.
function automobil(barva) { this.zbarveni = barva; this.rok_vyroby = 2001; this.nastartuj = function() {(alert("Vrumm"))} } var auto1 = new automobil("černé"); var auto2 = new automobil("modré"); var auto3 = new automobil("červené"); alert("Mám krásné " + auto1.zbarveni + " auto z roku " + auto1.rok_vyroby + "."); /* A to auto dělá... */ auto1.nastartuj();
Konstruktor se volá s operátorem new
. Každý objekt stvořený (inicializovaný) skrze konstruktor je instancí svého konstruktoru.
Výhoda právě popsaného řešení je z příkladu asi zřejmá. Inicializovali jsme objekty (instance) auto1
, auto2
, auto3
. Všechny mají vlastnosti zbarveni
, rok_vyroby
a metodu nastartuj()
, aniž bychom to explicitně přiřazovali pro každou instanci zvlášť, takže jsme si ušetřili hromadu psaní. Ať žije konstruktor!
Nyní si povíme něco o dědičnosti (inheritance). Ta v JavaScriptu zatím neexistuje. Alespoň ne v té klasické podobě, jak ji známe z jiných jazyků, např. z C++. Existuje zde ale jakási prototypová dědičnost. Prototyp je zvláštní objekt, který je přidružen každé funkci, tedy i k funkci konstruktoru. Všechny objekty inicializované skrze nějaký konstruktor dědí, respektive sdílejí vlastnosti a metody obsažené v prototypu svého konstruktoru, což se dá skvěle využít, když je potřeba přidat již definovanému konstruktoru nějakou novou vlastnost či metodu.
function automobil(barva) { this.zbarveni = barva; this.rok_vyroby = 2001; } automobil.prototype.nastartuj = function() {(alert("Vrumm"))} var auto1 = new automobil("černé"); auto1.nastartuj(); //vyhodí alert s hláškou "Vrumm"
Prototyp lze stejně dobře využít i na předdefinované objekty (konstruktory) jako Array()
, Object()
, String()
apod.
Regulární výrazy
Regulární výrazy (regular expressions, zkr. RE) znamenaly v programovacích jazycích nesmírný přínos pro práci s řetězci. Umožnily řetězce porovnávat s obecnými vzory a tím pomohly výrazně zkrátit mnohé úlohy. Bez regulárních výrazů se dnes programátoři prakticky neobejdou. Tato prostá a přitom elegantní technika má široké možnosti uplatnění. Jsou užitečné zejména při validaci (ověřování formální správnosti) vstupních dat, neboť umožňují výrazně snížit množství přijatých údajů nevhodného tvaru.
Následující tabulka obsahuje seznam znaků se speciálním významem.
Znak | Význam |
^ |
hledá shodu jen na začátku |
$ |
hledá shodu na konci |
* |
libovolný počet opakování (i 0) |
+ |
opakování (1 a vícekrát) |
? |
volitelný výskyt (0 nebo 1krát) |
{x} |
přesně x výskytů |
{x,} |
alespoň x výskytů |
{x,y} |
alespoň x, ale ne více než y výskytů |
() |
sekvence znaků v závorkách se uloží do paměti a dále se s nimi pracuje jako s jedním výrazem |
[] |
znak, který odpovídá některému ze znaků nebo znaku z rozsahů uvedených v závorkách. Příklady zápisu: [FuRz] , [5-9] , nebo [FuRz5-9] |
[^] |
opak předchozího; každý znak, který neodpovídá ničemu v závorce. Příklad zápisu: [^A-Z] |
. |
libovolný znak, kromě znaku nového řádku |
\ |
zrušení speciálního významu zvláštního znaku nebo přiřazení zvláštního významu běžnému znaku |
[\b] |
znak „backspace“ |
\b |
znak na hranici slova, před nebo za bílým místem (whitespace), který není zahrnut do podřetězce vyhovujícího regulárnímu výrazu; pro shodu s počátkem slova se umístí před znak (\bx) , pro shodu s koncem za něj (x\b) |
\B |
vnitřní část slova |
\d |
dekadická číslice |
\D |
opak dekadické číslice |
\f |
znak „form feed“ |
\n |
znak „new line“ |
\r |
znak „carriage return“ |
\s |
bílé místo (tj. mezera, tabulátor, nový řádek, …) |
\S |
opak bílého místa |
\t |
znak tabulátor |
\v |
znak vertikální tabulátor |
\w |
písmeno, číslice, nebo podtržítko |
\W |
cokoliv s výjimkou písmen, číslic a podtržítka |
Pokud si chcete otestovat vaši znalost regulárních výrazů, zde je k dispozici malý test.
Využití pro testování výskytu
Ke zjištění, zda se v určitém řetězci nachází podřetězec odpovídající danému RE, ideálně poslouží metoda test()
objektu RegExp. Jejím argumentem je testovaný řetězec. Vrací hodnotu typu boolean
. Následující příklad analyzuje akademický titul.
var titul = window.prompt("Napište své jméno (i s případným titulem)."); var diak = "áäčďéěíĺľňóôőöŕšťúůűüýřž"; var vzor = new RegExp("Dr[^a-z" + diak + "]"); var isDoctor = vzor.test(titul); if (isDoctor) window.alert("Óóó, Vy jste doktor.");
Další příklady využití naleznete v tomto článku: jak využít regulárních výrazů.
JSON (JavaScript Object Notation)
JSON (JavaScript Object Notation) je univerzální datový formát, který využívá konvence známých programovacích jazyků a díky tomu jimi může být podporován. Je založený na dvou strukturách:
- Kolekce párů klíč/hodnota. Ta bývá v rozličných jazycích nazývána jako objekt, záznam (record), struktura (struct), slovník (dictionary), hash tabulka, klíčový seznam (keyed list) nebo asociativní pole.
- Tříděný seznam hodnot. Ten je ve většině jazyků nazýván jako pole, vektor, seznam (list) nebo posloupnost (sequence).
Objekt je netříděná množina párů klíč/hodnota (key/value). Objekt je uvozený znakem {
a zakončený znakem }
, je tedy ohraničený složenými závorkami. Každý klíč je následovaný dvojtečkou a jednotlivé páry klíč/hodnota jsou od sebe oddělené čárkou. Příklad:
{"Jmeno" : "Petr Kovář", "Vek" : 21, "Svobodny" : true, "Majetek" : null}
Pole je setříděnou kolekcí hodnot. Začíná znakem [
a končí znakem ]
. Hodnoty jsou oddělené čárkou. Příklad:
["voda", "vápno", "cement", "písek"]
Klíč má charakter řetězce a jako takový musí být uzavřen v uvozovkách. Hodnotou může být řetězec, číslo nebo výrazy true, false, null
. Hodnotou může být dokonce i objekt nebo pole, vznikají tak vnořené struktury, předvedeme si to na dalším příkladu:
var JSONObject = {"string" : [ "number", "string", null, [ true, false ] ] };
Data do JSON obvykle nedáváme za účelem jejich pohřbení, nýbrž proto, abychom s nimi mohli později dále pracovat. Jak k nim však v JavaScriptu získat přístup? Postup je přesně stejný jako u každého jiného objektu a pole.
// v dialogovém okně vypíše hodnotu vlastnosti nazev_klice objektu nazev_objektu alert(nazev_objektu.nazev_klice); // v dialogovém okně vypíše třetí prvek pole nazev_pole alert(nazev_pole[2]);
Tento snadný přístup k datům je důvodem, proč se v AJAXu tak často využívá jako formát pro strukturovaná data JSON místo XML.
AJAX (Asynchronous JavaScript and XML)
V případě, že je potřeba obměnit jenom část obsahu stránky, je zbytečné ji znovu celou načítat. Uživatel by musel déle čekat a taky by to bylo plýtvání přenosovou kapacitou. Iframe
(stránka ve stránce) byl důvtipným řešením, které se i dnes hodně používá, avšak našlo se řešení ještě důmyslnější – AJAX. Funguje jednoduše: jsou-li potřeba nová data, odešle se prostřednictvím JavaScriptu HTTP požadavek na server, obdržená data se (opět JavaScriptem) zpracují a vloží do stránky.
Zpracování došlých dat souvisí s jejich formátem, například text či fragment HTML kódu se jen vloží do stránky pomocí vlastnosti innerHTML
, naopak v případě XML je možné procházet stromovou strukturu a pracovat přímo s jednotlivými uzly. Údaje formátu JSON lze nejsnadněji získat funkcí eval()
:
var myObject = eval('(' + http_request.responseText + ')');
V tomto způsobu ovšem spočívá jisté bezpečnostní riziko. Programátor, který jej použije, je povinen zajistit, že se do stahovaných dat nevloudí škodlivý kód! Jelikož však na programátory, stejně jako na ostatní příslušníky lidského rodu, není spolehnutí, bude zřejmě nezbytné přijít v další verzi JavaScriptu s JSON parserem, který bude jistě obezřetnější.
U některých webových prezentací využívajících AJAX bývá zhola nemožné dostat se použitím tlačítka Zpět k předchozímu obsahu dané prezentace nebo vytvořit odkaz na jiný než její výchozí obsah. Lze to napravit tím, že se každému jednotlivému obsahu přidělí tzv. kotva, takže každý obsah bude mít svou adresu (např.: http://priklad.cz/ajax.html#cast3), na níž bude možno odkázat a podle té části za mřížkou se pak vygeneruje žádaný obsah.
Canvas
Dynamické generování obrázků PHP skriptem má své drobné nevýhody – zatěžování serveru, pomalejší odezvu atd. Je proto vhodnější v případech, kdy se obrázky generují na základě uživatelem dodaných parametrů, dát přednost JavaScriptu.
Element canvas
představuje plochu o výchozích rozměrech 300 × 150 pixelů, na níž lze JavaScriptem kreslit různé geometrické tvary – čáry, kruhy, obdélníky atd. – a sestavovat z nich jednoduché obrázky.
Kód pro Canvas je vhodné podmínit, protože zastaralé prohlížeče Canvas nepodporují a provádění skriptu by v nich skončilo chybou.
var canvas = document.createElement('canvas'); if (canvas.getContext) { // podmínku splní jen prohlížeče podporující Canvas var obrazek = canvas.getContext('2d'); obrazek.fillRect(20,20,10,15); // nakreslí černý obdélníček document.body.appendChild(canvas); // vloží canvas do stránky }
Jiné tvary než obdélníky a čtverce se kreslí pomocí tzv. cest, viz příští příklad.
Nejdůležitější vlastnosti a metody dvourozměrného kontextu:
strokeStyle
– barva čáry (implicitněblack
)<fillStyle
– barva výplně (implicitněblack
)fillRect(x,y,w,h)
– nakreslí vyplněný obdélníkstrokeRect(x,y,w,h)
– nakreslí orámovaný obdélníkclearRect(x,y,w,h)
– smaže obdélníkovou oblastfillText(text,x,y,max)
– napíše text, poslední argument je maximální šířkabeginPath()
– inicializuje (novou) cestuclosePath()
– dokončí cestumoveTo(x,y)
– přerušení cesty a přemístění se na zadané souřadnicelineTo(x,y)
– přímá cesta na zadané souřadnicerect(x,y,w,h)
– obdélníková cestaarc(x,y,r,úhel,úhel,směr)
– cesta po obvodu kruhu (proti směru hodinových ručiček, je-li posledním argumentemtrue
); zadané souřadnice náleží středu kruhu, úhly (první výchozí, druhý koncový) se zadávají v radiánecharcTo(x1,y1,x2,y2,r)
– cesta po obvodu kruhu přes první bod ke druhémuquadraticCurveTo(xcp, ycp, x, y)
– cesta po kvadratické křivcebezierCurveTo(xcp1, ycp1,xcp2, ycp2,x,y)
– cesta po Bézierově křivcelineWidth
– tloušťka čáry (implicitně1
)lineCap
– zakončení čáry;butt
,round
, nebosquare
isPointInPath(x,y)
– zjišťuje, zda cesta prochází daným bodemfill()
– vyplní barvou vnitřek obrazce zformovaného cestoustroke()
– vykreslí cestu
Vysvětlivky: x = pozice na ose x, y = pozice na ose y, w = šířka, h = výška, r = poloměr, cp = bod, k němuž křivka uhýbá
function Vykres() { var canvas = document.createElement('canvas'); var obrazek = canvas.getContext('2d'); obrazek.fillStyle = "green";//zelené výplně obrazek.lineWidth = 4;// šířka čáry: 4 obrazek.beginPath(); // nová cesta // kruh o poloměru 50 obrazek.arc(52,52,50,0,Math.PI*2,false); obrazek.stroke(); // vykreslí černý kruh... obrazek.fill(); // ...se zelenou výplní obrazek.beginPath(); // nová cesta obrazek.strokeStyle = "navy"; // další čáry budou modré obrazek.moveTo(200,100); // přesun pozice // formování pravoúhlého trojúhelníku obrazek.lineTo(120,100); // první čára obrazek.lineTo(200,20); // druhá čára obrazek.closePath(); // dokončí trojúhelník obrazek.stroke(); // čáry se vykreslí (modře) document.body.appendChild(canvas); }
A výsledek? …no hrůza!
Odkazy
- Začínáme s HTML5 canvasem (M. Hassman)
- Canvas tutoriál (mozilla.org)
Klientská datová úložiště
Webové aplikace často potřebují ukládat informace o uživatelově činnosti. Tento úkol dosud plnili cookies, cookies se však již chystají do důchodu, takže nemá valný smysl o nich referovat. Nahradit by je měla datová úložiště typu sessionStorage, localStorage a database. Údaje v prvních dvou úložištích jsou uskladněny v podobě seznamu položek. Každá položka je tvořena dvojicí klíč : hodnota.
<p> Vítejte na našem skvělém webu! Je to zatím Vaše <span id="count">neznámo kolikátá </span>návštěva. </p> <script> var counter = document.getElementById('count'); if (!localStorage.pageLoadCount) localStorage.pageLoadCount = 0; localStorage.pageLoadCount += 1; counter.textContent = localStorage.pageLoadCount + ". "; </script>
Na uvedeném příkladu jsme si ukázali využití objektu localStorage
. S objektem sessionStorage
, který uchovává data platná po dobu aktuální relace (tj. do zavření okna nebo panelu prohlížeče), se pracuje naprosto stejně.
Třetí typ datového úložiště se svou sofistikovaností velmi liší od předešlých dvou, přestože se opět jedná o persistentní klientské datové úložiště. Má databázový charakter a slouží pro ukládání složitěji strukturovaných dat. Záznamy jsou indexovány.
Několik slov na závěr
Na internetových serverech lze narazit na mnoho tutoriálů o JavaScriptu. Některé z nich, např. w3schools.com, jsou poměrně rozsáhlé a ve srovnání s nimi bude zřejmě tato skromná syntéza působit trochu uboze, ale i ona může být užitečná, hlavně pro ty, kteří se potřebují v JavaScriptu rychle zorientovat.
Mohlo by vás také zajímat
-
Optimalizace a zlepšení výkonu kódu: tipy a triky
14. srpna 2023 -
AI v programování: Jak používat GitHub Copilot (část 1)
12. února 2024 -
Umělá inteligence v IT
27. září 2023
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024
YOYO
Úno 25, 2010 v 5:43Moc děkuji za pěkné shrnutí :)