E N C Y K L O P E D I E
W E B D E S I G N E R A
Začínáme
JavaScript
Základy programování, webové formuláře, DOM a Ajax
www.zonerpress.cz
Kevin Yank Cameron Adams
Začínáme s JavaScriptem
Kevin Yank a Cameron Adams
uvod.indd 1
30.4.2008 9:27:25
Simply JavaScript Kevin Yank and Cameron Adams Original English language edition published by SitePoint Pty, Ltd., 424 Smith Street Collingwood, VIC Australia 3066. Copyright © 2007 by SitePoint Pty, Ltd. Czech language edition copyright © 2008 by ZONER software, s.r.o. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from SitePoint, Ltd. Originální anglické vydání vydal SitePoint Pty, Ltd., 424 Smith Street Collingwood, VIC Australia 3066. Copyright © 2007 SitePoint Pty, Ltd. České vydání vydal ZONER software, s.r.o., copyright © 2008. Všechna práva vyhrazena. Žádná část této publikace nesmí být reprodukována nebo předávána žádnou formou nebo nějakým jiným způsobem, elektronicky ani mechanicky, včetně fotokopií, natáčení ani žádnými jinými systémy pro ukládání bez výslovného svolení SitePoint, Ltd.
Začínáme s JavaScriptem Autoři: Kevin Yank a Cameron Adams. Copyright © ZONER software, s.r.o. Vydání první v roce 2008. Všechna práva vyhrazena. Zoner Press Katalogové číslo: ZR738 ZONER software, s.r.o. Nové sady 18, 602 00 Brno Překlad: RNDr. Jan Pokorný Odpovědný redaktor: Miroslav Kučera Šéfredaktor: Ing. Pavel Kristián DTP: Miroslav Kučera Informace, které jsou v této knize zveřejněny, mohou byt chráněny jako patent. Jména produktů byla uvedena bez záruky jejich volného použití. Při tvorbě textů a vyobrazení bylo sice postupováno s maximální péčí, ale přesto nelze zcela vyloučit možnost výskytu chyb. Vydavatelé a autoři nepřebírají právní odpovědnost ani žádnou jinou záruku za použití chybných údajů a z toho vyplývajících důsledků. Všechna práva vyhrazena. Žádná část této publikace nesmí být reprodukována ani distribuována žádným způsobem ani prostředkem, ani reprodukována v databázi či na jiném záznamovém prostředku či v jiném systému bez výslovného svolení vydavatele, s výjimkou zveřejnění krátkých částí textu pro potřeby recenzí. Zdrojové soubory ke knize: http://zonerpress.cz/download/zdrojove-kody-zaciname-s-javascriptem.zip Veškeré dotazy týkající se distribuce směřujte na: Zoner Press ZONER software, s.r.o. Nové sady 18, 602 00 Brno tel.: 532 190 883, fax: 543 257 245 e-mail: knihy@zoner.cz http://www.zonerpress.cz
ISBN 978-80-86815-94-7
uvod.indd 2
30.4.2008 9:27:52
Bez tebe, Liso, bych tuto knihu nikdy nenapsal. Mohu jen doufat, že Ti dokážu oplatit tolik lásky a podpory, kolik jsem jí od Tebe dostal. – Cameron Jessice, mé souputnici, limetce v mé limonádě. – Kevin
uvod.indd 3
30.4.2008 9:27:52
4
O autorech a vydavateli Kdo je Kevin Yank Jako technický ředitel SitePointu sleduje Kevin Yank pozorně všechno, co je ve webové technologii nové a vzrušující. Proslavil se svou knihou Build Your Own Database Driven Website Using PHP & MySQL1, která vyšla už ve třetím vydání. Kevin také píše do SitePoint Tech Times2, což je zdarma poskytovaný čtrnáctidenní e-mailový bulletin, který má přes 150 000 odběratelů po celém světě. Když zrovna nemluví na nějaké konferenci, nebo není na návštěvě u přátel nebo doma u rodiny v Kanadě, najdete ho v Austrálii v Melbourne, kde se baví improvizovaným komediálním divadlem Impro Melbourne3 a létáním na malých letadlech. Jeho osobní blog je Yes, I’m Canadian4.
Kdo je Cameron Adams Cameron Adams získal své zázemí v počítačové vědě prostřednictvím téměř desetiletých zkušeností v grafickém designu, takže má jedinečný přístup k návrhům rozhraní. Svých dovedností využívá vždy, když si pohrává s prolínáním designu a kódu. Usiluje o to, aby vytvářel weby a aplikace, které budou něčím zajímavé a novátorské. Protože pracoval nejenom pro velké korporace, vládu, neziskové organizace, ale také pro malé rozjíždějící se firmy, začíná mu být pomalu jasné, co vlastně tvoří podstatu Internetu. Kromě projektů, které dělá proto, aby dokázal splatit své účty za elektřinu, přemítá Cameron o webovém designu na svém velmi respektovaném webovém blogu The Man in Blue5. Napsal několik knih na různá témata – od JavaScriptu až k CSS a designu. Někdy ho najdete v Melbourne, jindy rád létá po světě, aby si mohl pohovořit o designu a programování s různými spřátelenými experty. Jestliže na něj narazíte v nějakém baru, kupte mu Baileys a řekněte "ahoj".
Co je SitePoint SitePoint se specializuje na vydávání zábavného, praktického a snadno pochopitelného výukového obsahu pro webové profesionály. Chcete-li se podívat na naše knihy, bulletiny, články a komunitní fóra, navštivte http://www.sitepoint.com/.
1
http://www.sitepoint.com/books/phpmysql1/
2
http://www.sitepoint.com/newsletter/
3
http://www.impromelbourne.com.au/
4
http://yesimcanadian.com/
5
http://themaninblue.com/
uvod.indd 4
30.4.2008 9:27:53
5
Obsah O autorech a vydavateli Poděkování
10
Předmluva
11
Komu je kniha určena?
12
Co obsahuje tato kniha?
12
Konvence
14
Sdělte nám svůj názor
14
Zdrojové kódy
15
Kapitola 1
Tři vrstvy webu
17
Udržujte věci oddělené
18
Tři vrstvy
19
Obsah s HTML
21
Prezentace s CSS
22
Chování s JavaScriptem
23
Správná cesta
24
Knihovny JavaScriptu
25
Začněte!
26
Kapitola 2
Programování s JavaScriptem
27
Spuštění javascriptového programu
27
Příkazy – sousta kódu pro prohlížeč
30
Komentáře – sousta pouze pro vás
30
Proměnné – ukládání dat pro váš program
31
Typy proměnných – různé typy pro různá data
34
Podmínky a cykly – řízení toku programu
43
Podmínky – vytváříme rozhodnutí
43
Cykly – automatizace opakujících se úloh
uvod.indd 5
4
49
Funkce – psaní kódu pro pozdější potřeby
54
Argumenty – předávání dat do funkce
55
Příkazy return – výstup dat z funkce
56
Obor – oddělte proměnné
57
30.4.2008 9:27:53
6 Objekty
58
Nevtíravé skriptování ve skutečném světě
61
Shrnutí
62
Kapitola 3
Přístup k dokumentu
Objektový model dokumentu – mapování HTML
63
Textové uzly
65
Uzly atributů
66
Přístup k uzlům, s nimiž chcete něco dělat
67
Vyhledání prvku podle ID
67
Vyhledávání prvků podle názvu značky
70
Vyhledávání prvků podle názvu třídy
73
Navigace po stromu DOM
77
Interakce s atributy
80
Změna stylů
81
Změna stylů pomocí třídy Příklad – pruhované tabulky
83 87
Vyhledání všech tabulek s třídou dataTable
88
Postupné získání řádků pro každou tabulku
88
Přidání třídy alt každému sudému řádku
90
Dejme všechno dohromady
91
Průzkum knihoven
93
Prototype
93
jQuery
94
Dojo
95
Shrnutí
Kapitola 4
95
Události
97
Historie zpracování událostí
97
Obsluha události
98
Výchozí akce
101
Klíčové slovo this
103
Problém s obsluhou události
105
Posluchači událostí
uvod.indd 6
63
106
30.4.2008 9:27:53
7 Výchozí akce
109
Propagace událostí
111
Klíčové slovo this
115
Internet Explorer a díry v paměti
117
Dejme všechno dohromady
117
Příklad – atraktivní vysvětlivky Statická stránka
121
Aby se věci mohly začít dít
121
Metody tažného koně
122
Dynamické styly
126
Dejme všechno dohromady
128
Příklad – harmonika
129
Statická stránka
130
Metody tažného koně
131
Dynamické styly
133
Dejme všechno dohromady
135
Průzkum knihoven
142
Shrnutí
143
Kapitola 5
Animace
145
Principy animace
145
Řízení času s JavaScriptem
146
Proměnné a setTimeout
150
Zastavování časovače
152
Vytvoření opakujícího se časovače
153
Jak zastavit setInterval
154
Revize atraktivních vysvětlivek
154
Animace ze staré školy v novém hávu
156
Pohyb založený na cestě
159
Animace ve dvou dimenzích
166
Vytváření realistického pohybu
168
Rozvíjejte své dovednosti
173
Revize ovládacího prvku harmonika Harmonika s animovaným vzhledem
uvod.indd 7
120
173 173
30.4.2008 9:27:53
8 Změny v kódu Průzkum knihoven script.aculo.us Shrnutí
Kapitola 6
181 181 183
Vylepšení formulářů
Rozšíření DOM HTML
185 186
Příklad – závislá pole
188
Příklad – kaskádové nabídky
196
Ověřování formuláře
207
Zachytávání pokusů o odeslání formuláře
207
Regulární výrazy
209
Příklad – opětovně využitelný ověřovací skript
214
Vlastní formulářové ovládací prvky
219
Příklad – slider
219
Průzkum knihoven
231
Kontrola formuláře
231
Vlastní ovládací prvky
233
Shrnutí
Kapitola 7
234
Chyby a ladění
235
Nic se neděje!
236
Běžné chyby
240
Syntaktické chyby
240
Chyby při běhu
244
Logické chyby
247
Ladění s Firebugem
250
Shrnutí
256
Kapitola 8
Ajax
XMLHttpRequest – servírování soust obsahu tak akorát do úst
uvod.indd 8
174
257 257
Vytvoření objektu XMLHttpRequest
258
Volání serveru
261
Práce s daty
264
30.4.2008 9:27:53
9 Několik slov ke čtečkám obrazovky
266
Ajax v akci
266
Nepřerušované odesílání formuláře přes Ajax
277
Průzkum knihoven
284
Prototype
285
Dojo
286
jQuery
287
YUI
287
MooTools
288
Shrnutí
Kapitola 9
288
Výhledy do budoucna
Vylepšení bohatosti webů
290
Snadné průzkumy
290
Snadná vizualizace
291
Jedinečná interakce
292
Bohaté internetové aplikace
294
Komponenty (widgety)
297
JavaScript mimo weby
297
Průzkum knihoven
298
Dojo
299
Google Web Toolkit
301
Shrnutí
Příloha A
302
Knihovna JavaScriptu Core
303
Objekt
303
Metody posluchačů události
305
Svépomocné startování (bootstrapping)
313
Metody pro správu tříd CSS
315
Získávání vypočtených stylů
316
Kompletní knihovna
316
Rejstřík
uvod.indd 9
289
323
30.4.2008 9:27:53
10
Poděkování Kevin Yank Rád bych poděkoval Marku Harbottleovi a Luku Cuthbertsonovi, spoluzakladateli SitePoint a generálnímu řediteli. Oba tito lidé si mě sklonku roku 2006 zavolali a podruhé v mé kariéře mě ubezpečili, že když učiním krok stranou od svých každodenních aktivit u SitePointu a začnu psát tuto knihu, nebude se jednat o posun k horšímu v mé kariéře. Také dlužím drink Simonu Mackie, který měl prvotní nápad. Doufejme, že mu ho někdo z vás koupí! Jessice za ty mnohé večery, kdy jsem zůstával v kanceláři a psal ještě dlouho poté, co jsem slíbil, že už budu doma, a za nezměrnou podporu a trpělivost, s nimiž mě vítala, když jsem konečně dorazil. Dlužím jí něco hodně velkého čokoládového. A také děkuji více než 150 000 čtenářům bulletinu SitePoint Tech Times, s nimiž jsem sdílel mnohé z nápadů, které se nakonec uplatnily v této knize. Tito čtenáři mi poskytli cenné názory, které pro mě často byly výzvou. Jsem za ně vděčný.
Cameron Adams Znalosti, jichž jsem nabýval o JavaScriptu, pocházejí z tolika zdrojů, že je nemožné, abych je zde všechny vyjmenoval. Cokoliv z toho, co dokážu předat dál, znám pouze díky příspěvkům stovek – ne-li tisíců – nezištných lidí, kteří obětovali svůj drahocenný čas a poskytli své vědomosti, aby z nich mohli těžit jiní. Budete-li někdy v situaci, že byste se mohli k těmto hlasům přidat, pokuste se o to co nejusilovněji. Přesto bych chtěl zapět oslavnou tirádu na tým Webmonkey – konkrétně si ji zaslouží Thau a Taylor, kteří mě inspirovali na začátku. Také bych rád vyjádřil svůj dík některým kolegům programátorům, kteří byli vždy po ruce, když jsem potřeboval rychle získat odpověď na nějaký dotaz. Jedná se o tyto kolegy: Derek Featherstone, Dustin Diaz, Jonathan Snook, Jeremy Keith, Peter-Paul Koch a Dan Webb. Děkuji vám všem!
uvod.indd 10
30.4.2008 9:27:53
11
Předmluva Při prvotním pohledu vypadá JavaScript jako jednoduchý programovací jazyk, který umožňuje za pochodu měnit webové stránky v době, kdy jsou zobrazeny ve webovém prohlížeči. Za jak dlouho se asi tak dá naučit? Zdá se, že se dá zmáknout za jedno odpoledne. JavaScript je ale mocnější, než by se vám mohlo zdát. Kdybyste byli fandové doktora Who, mohl by vám připadat jako Tardis programovacích jazyků. Jestliže nefandíte doktorovi Who, dívejte se mi do očí, hoši (a děvčata), a poslouchejte, co vám budu povídat. Dáváte všichni pozor? Jimmy, dej pryč ty své hračky. Jak jsem řekl – JavaScript pouze vypadá, že je jednoduchý. Nicméně v průběhu jeho desetileté historie se zdálo, že nejlepší taktika, jak s ním něco udělat, bylo měnit jeho fazónu každou sezónu. A rad, jak psát dobrý kód, je všude plno: "Dělejte to takhle – poběží to rychleji!", "Použijte tenhle kód – poběží ve více prohlížečích!", "Od téhle funkce ruce pryč – způsobuje díry v paměti!". V mnoha jiných knihách o JavaScriptu – z nichž některé z nich jsou od velmi renomovaných autorů v branži – zvládnete pouze hrst jednoduchých řešení jednoduchých problémů. A pak, až se jednoho krásného dne pokusíte sami vyřešit skutečný problém ze skutečného světa, zjistíte, že tyto knihy vám poskytly pouze dlouhý provaz, na kterém se dokážete sami oběsit. Když pak v zoufalství přejdete na web, abyste si prohlédli nějaký příklad, který dělá to, co potřebujete, pravděpodobně nebudete rozumět kódu JavaScriptu, který v něm najdete, protože v knize, kterou jste si koupili, se neprobírají mnohé skutečně potřebné a prospěšné pojmy jazyka, jako jsou doslovná syntax objektu (object literal syntax; umožňuje vytvořit objekt i jeho obsah jediným příkazem), posluchač události (event listener) nebo uzávěra (closure; umožňuje funkci definované uvnitř jiné funkce přístup k lokálním proměnným vnější funkce, i když ta už neběží). Usilovali jsme se, aby tato kniha byla jiná. Od úplně první stránky vám ukážeme tu pravou cestu, jak používat JavaScript. Protože budete pracovat s plnohodnotnými propracovanými příklady, které je možné okamžitě vsunout do profesionálně navrženého webu, získáte nejen sebedůvěru pro psaní vlastního kódu JavaScriptu, ale také porozumíte kódu, který napsali jiní. Budete dokonce schopni rozpoznat zhoubný a staromódní kód, který napáchá více škody než užitku! Na různých místech této knihy jsme se pokusili poskytnout i něco navíc, nikoliv pouhé základy. Konkrétně probereme některé z nových vývojářských technik, jimiž je JavaScript poháněn (jako je Ajax), a které mění tvářnost webu. Také jsme zařadili sekce, v nichž prozkoumáme novou úrodu knihoven JavaScriptu, jako jsou jQuery, Prototype, Yahoo! UI a Dojo, takže naše publikace je v současnosti jedinou knihou o JavaScriptu pro začátečníky, ve které se probírají i tyto mocné nástroje zvyšující efektivitu vývojáře. Tohle všechno sice způsobilo, že bylo mnohem obtížnější napsat takovou knihu, ovšem na druhou stranu jsme za ni také dostali hodně prachů.
uvod.indd 11
30.4.2008 9:27:53
12
Komu je tato kniha určena? Je možné, že jste ještě nikdy v životě neviděli ani jediný řádek kódu JavaScriptu, nebo jste naopak viděli až příliš mnoho řádků kódu, který nedělal to, co jste očekávali. Ať už je to jak chce, v této knize se dozvíte, jak zařídit, aby pro vás JavaScript pracoval řádně a dobře. Předpokládáme, že jste poměrně slušně obeznámeni s tím, jak se navrhují weby s HTML (HyperText Markup Language) a kaskádovými stylovými předpisy (Cascading Style Sheets, CSS). Neočekává se od vás, že budete experty na tyto jazyky, ale jak brzy uvidíte, JavaScript je pouze dalším dílkem do skládačky. Čím budete lépe rozumět základním technikám webového designu, tím lépe je budete moci vylepšovat s JavaScriptem. Pokud si potřebujete osvěžit své znalosti, vřele doporučujeme knihy Eric Meyer o CSS – kompletní průvodce a Webdesign s webovými standardy, které v češtině vydalo nakladatelství Zoner Press (www.zonerpress.cz).
Co obsahuje tato kniha? Kapitola 1 – Tři vrstvy webu Když se učíte pracovat s JavaScriptem, je velmi důležité naučit se rozlišovat, kdy je pro práci, která leží před vámi, tím pravým nástrojem. Někdy totiž může poskytnout lepší řešení obyčejný kód HTML a CSS. Než se ponoříme do výuky JavaScriptu, strávíme trochu času tím, že si stručně zrekapitulujeme, jak se budují weby s HTML a CSS, a podíváme se, jak do nich zapadá JavaScript.
Kapitola 2 – Programování s JavaScriptem JavaScript je programovací jazyk. Abyste s ním mohli pracovat, musíte mít představu o tom, jak pracují počítačové programy, což do jisté míry znamená, že se musíte naučit myslet jako počítač. Prosté pojmy, které zavádíme v této kapitole – příkazy, proměnné, výrazy, cykly, funkce a objekty – jsou základní stavební kameny každého programu JavaScriptu, který budete vytvářet.
Kapitola 3 – Přístup k dokumentu Zřejmě nepatříte mezi programátory, co se baví tím, že píší kód JavaScriptu jen pro sebe, pro své vlastní potěšení. Jakožto klidní a vyrovnaní weboví vývojáři budete patně chtít pomocí JavaScriptu měnit obsah svých webových stránek pomocí objektového modelu dokumentu (Document Object Model, DOM). Máte štěstí, protože tomuto tématu se věnuje celá třetí kapitola!
Kapitola 4 – Události Tohle bude nepochybně nejvíce akční kapitola plná událostí (ha ha … to jsem se ale vtipně vyjádřil). Dozvíte se, jak psát programy JavaScriptu, které reagují na akce uživatelů, kteří komunikují s nějakou webovou stránkou. Jak sami uvidíte, dá se to dělat mnoha způsoby, nicméně úroveň podpory pro tyto věci je u současných prohlížečů různá.
uvod.indd 12
30.4.2008 9:27:53
13 Kapitola 5 – Animace Dobře, dobře. O nepatrném přínosu této kapitoly k celkové k využitelnosti stránek se dá plkat celý den, ale my moc dobře víme, že nebudete mít klid, dokud nebudete vědět, jak se dají tyhle věcičky strkat do stránek, tuhle a támhle. V této kapitole se dozvíte vše potřebné.
Kapitola 6 – Vylepšení formulářů Vím, že si myslíte, že jsou formuláře nuda. Nikdo není takový, že by ráno vyskočil z postele, navlékl si na ruce boxerské rukavice a vzkřikl "Dneska si to rozdám s několika formuláři!" Nuže – až své formuláře vylepšíte triky z této kapitoly, možná se takovými stanete. A abych nezapomněl, v této šesté kapitole vám také ukážeme, jak dosáhnout přetahování nějakého prvku na stránce.
Kapitola 7 – Chyby a ladění Když jde něco šejdrem v jiných programovacích jazycích, počítač obvykle – a až do zblbnutí – produkuje neměnný proud chybových zpráv, dokud závadu neopravíte. S JavaScriptem ovšem počítač pouze pokrčí rameny a vrhne na vás pohled, jako by chtěl říci: "Bude se něco dít?". Angličtina (a ani čeština) opravdu není mateřský jazyk vašeho počítače. Co se dá od něho v tomto ohledu čekat, když ho vyrobili někde na Tchajwanu? V této kapitole vám ukážeme, jak se opravují skripty, které se nechovají podle vašich představ.
Kapitola 8 – Ajax Možná jste už slyšeli o něčem, co se jmenuje Ajax. Tato technologie umožňuje, aby vaše webové stránky mohly vypadat jako desktopové aplikace a vachrlaté akciové společnosti jako solidní investice. Zařadili jsme ho do knihy z obou důvodů.
Kapitola 9 – Výhledy do budoucna JavaScript není takový, že by měl budoucnost. JavaScript je totiž sám budoucností! Dobrá, možná si myslíte, že to bude ještě chvíli trvat, ale až si přečtete tuto kapitolu a poznáte mnohé okouzlující věci, které JavaScript umožňuje, doufáme, že změníte názor.
Příloha A – Knihovna Core JavaScriptu Jak se budete postupně propracovávat touto knihou, budete vytvářet kód pro řešení mnoha běžně se vyskytujících úloh. Abyste nemuseli stále znovu a znovu vytvářet stejné části kódu, shromáždili jsme ho do naší javascriptové knihovny Core, kterou budete moci opětovně využívat ve svých vlastních projektech, čímž si ušetříte spoustu hodin psaní. Tato příloha poskytuje shrnutí a rozbor veškerého kódu, který jsme soustředili do této knihovny (včetně pokynů, jak ji používat).
uvod.indd 13
30.4.2008 9:27:53
14
Konvence Abyste si mohli z textu této knihy odnést co nejvíce a mohli jej snadno sledovat, používáme v knize několik následujících konvencí. Rámečky, jako je tento, obsahují důležité informace (tipy, poznámky nebo varování), které přímo související s okolním textem, a které byste si měli ve vlastním zájmu zapamatovat.
Co se týče použitého formátování v textu:
Klávesové zkratky píšeme takto: Ctrl+A
Názvy souborů, URL a kód v textu píšeme takto: nejaka.promenna
Zdrojový kód uvádíme dvěma způsoby: V ukázkách kódu zdůrazňujeme nové a důležité úseky tučným řezem. Tučné zvýraznění není použito u kódu, který není v dané souvislosti tolik podstatný, nebo se neobjevuje poprvé.
Pokud se kód nachází ve zdrojových kódech k této knize, uvidíte nad daným výpisem programu příslušný název souboru, jako zde: example.css .footer { background-color: #CCC; border-top: 1px solid #333; }
Jestliže daný výpis obsahuje pouze část uvedeného souboru, je použito slovo výňatek: example.css (výňatek) border-top: 1px solid #333;
Sdělte nám svůj názor Jako čtenáři této knihy se stáváte těmi nejdůležitějšími kritiky a komentátory. Vážíme si vašeho názoru a chtěli bychom vědět, co děláme správně, co bychom mohli dělat lépe, ve kterých oblastech bychom měli publikovat a také vaše další podnětné myšlenky, o které jste ochotni se s námi podělit. Jako odborný redaktor Zoner Press vítám vaše názory. Můžete mi psát – poslat e-mail nebo dopis – a sdělit mi, co se vám v této knize líbilo nebo nelíbilo, stejně tak, co bychom měli udělat, aby naše další knihy byly lepší. Pokud mi napíšete, nezapomeňte prosím připojit název knihy, ISBN, jméno
uvod.indd 14
30.4.2008 9:27:53
15 autora, vaše jméno, telefon, fax nebo e-mail. Pozorně zhodnotím vaše názory a poskytnu je autorovi a redaktorům, kteří pracovali na této knize. Prosím, vězte, že nemohu pomoci s technickými problémy, které se týkají obsahu knihy, a že díky velkému množství e-mailů, které dostávám, nemohu zaručit odpověď na každou zprávu. E-mail: miroslav.kucera@zoner.cz nebo knihy@zoner.cz. Adresa: Zoner Press, ZONER software, s.r.o., Miroslav Kučera, Nové sady 18, 602 00 Brno.
Zdrojové kódy Když si budete procházet příklady v této knize, můžete zdrojový kód opisovat ručně, nebo můžete použít doprovodné soubory ke knize. Veškeré zdrojové kódy, které jsou použity v této knize, jsou dostupné ke stažení na následující adrese (velikost 1 018 kB): http://zonerpress.cz/download/zdrojove-kody-zaciname-s-javascriptem.zip
Po stažení souboru se zdrojovými kódy ho jednoduše rozbalte vaším komprimačním nástrojem.
uvod.indd 15
30.4.2008 9:27:53
16
uvod.indd 16
30.4.2008 9:27:54
KAPITOLA 1 Tři vrstvy webu "Byl jednou jeden … král", doplní promptně mí malí posluchači. "Ne, děti, špatně. Byl jednou jeden kus dřeva …" – Pinocchiova dobrodružství I bez JavaScriptu se dá hodně udělat. S jazykem HTML1 (Hypertext Markup Language) dokážete vyprodukovat komplikované dokumenty, které spletitě popisují obsah stránky – a význam tohoto obsahu – až do těch nejmenších detailů. Pomocí kaskádových stylových předpisů (Cascading Style Sheets, CSS) můžete obsah prezentovat nesčíslnými způsoby a s obměnami, které mohou být nenápadné (jako je změna jen jediné barvy), nebo naopak velmi nápadné (náhrada textu obrázkem). Bez ohledu na to, do čeho vaši stránku oblečete, s HTML a CSS se dá dosáhnout jen statické krásy figuríny ve výloze obchodního domu – nebo přinejlepším toho, že jde-li někdo okolo, figurína se začne vratce a toporně hýbat, s monstrózně robotickými gesty. S JavaScriptem vdechnete nemotorné loutce život, čímž zároveň sami sebe, jakožto stvořitele nové živé bytosti, pozdvihnete z nevýrazného prodejce na mistra webového designu! Ovšem to, zdali se bude vaše nová kreace pohybovat ladně jako modelka na přehlídkovém molu, nebo se bude kulhavě belhat a šourat jako zrůda doktora Frankensteina, závisí nejenom na kvalitě výchozího kódu HTML a CSS, ale také na kódu JavaScriptu, kterým jste vaší kreaci vdechli život. A proto, než se společně začneme učit dělat zázraky, věnujme trochu času na rekapitulaci, jak se vytvářejí weby, které vypadají dobře uvnitř i navenek, a jak do celé této skládačky zapadá JavaScript.
1
V knize se zkratkou HTML odkazujeme na HTML i XHTML. Co zvolíte vy, záleží jen na vás, JavaScriptu se to v podstatě netýká. Pro případ, že by to pro vás bylo podstatné, vězte, že kód HTML uváděný v této knize je platný XHTML.
Kapitola 01.indd 17
30.4.2008 9:28:36
18
Kapitola 1 – Tři vrstvy webu
Udržujte věci oddělené Není to tak dávno, co profesionální weboví designéři škodolibě nacpali HTML, CSS a JavaScript do jediného souboru, který pak pojmenovali index.html2 a říkali mu webová stránka. I dnes to můžete dělat tímto způsobem, ale připravte se na to, že v takovém případě se o vás vaši spolupracovníci nebudou vyjadřovat příliš lichotivě.
V jisté fázi vývoje WWW stránek designéři zjistili, že kód, který píší při vytváření webové stránky, dělá následující tři zásadní věci:
Popisuje obsah stránky.
Specifikuje prezentaci obsahu.
Řídí chování obsahu.
Dále přišli na to, že budou-li tyto tři typy věci od sebe oddělovat – jak je to znázorněno na obrázku 1.1 – hodně jim to usnadní práci, a také to napomůže k tomu, aby webové stránky lépe fungovaly i za nepříznivých okolností, např. když mají uživatelé ve svých prohlížečích vypnutý JavaScript. Počítačoví experti ovšem tohle vědí už léta a dokonce tomuto principu přidělili odbornou zkratku SoC (Separation of Concerns, doslova "oddělení věcí").
2
Nebo default.htm, pokud mají mozek vymytý společností Microsoft.
Kapitola 01.indd 18
30.4.2008 9:28:46
Začínáme s JavaScriptem
19
Obrázek 1.1. Oddělení věcí. Musíme ale říci, že jedna věc je vědět, že to tak má být, a druhá věc je skutečně to tak dělat – zejména tehdy, když nejste počítačový expert. Já jsem počítačový expert, a přesto jsem neustále v pokušení dělat věci nesprávně. V pohodičce si edituji kód HTML, který popisuje obsah nějaké webové stránky, když mě najednou napadne, jak by bylo pěkné, kdyby text měl poněkud jiný odstín šedé, kdyby byl posunutý kousíček doleva, a kdyby na pozadí byl můj legrační obličej, jak jsem vyfotil sám sebe na posledním firemním večírku vydavatelství. Protože o sobě moc dobře vím, jak jsem často roztěkaný, chtěl bych ty změny udělat raději ihned, než na ně zapomenu. Co myslíte, že je snazší: otevřít samostatný soubor CSS, abych modifikoval stylový předpis stránky, nebo jednoduše napsat příslušné vlastnosti stylu rovnou do HTML kódu, který zrovna edituji? Podobně jako u jiné pracovní činnosti, i zde je potřebná určitá sebekázeň, pokud chcete udržet různé typy kódu odděleně od sebe. Jakmile však pochopíte, jaké to přináší výhody, budete i vy schopni najít dost pevné vůle, abyste odolali pokušení udělat to tou přímou a zdánlivě snazší cestou.
Tři vrstvy Udržovat různé druhy kódu od sebe oddělené vždy, když to jenom trochu jde, je dobrý návyk v každém druhu programování. Části takového kódu se snadněji opětovně využívají v budoucích projektech, nehledě na to, že až dokončíte kód, který píšete, bude objem duplicitního kódu menší (takže po uplynutí několika měsíců – nebo let – se budou snadněji hledat a opravovat případné vzniklé chyby a problémy). Pokud jde o weby, je tu ještě jeden důvod navíc, proč udržovat kód oddělený. Umožní vám totiž brát v úvahu mnoho různých způsobů, jimiž lidé přistupují k webovým stránkám. Podle toho, jaké máte publikum, většina návštěvníků pravděpodobně používá dobře vybavené prohlížeče s podporou nejnovějších verzí CSS a JavaScriptu, ovšem spousta z nich může trpět pod re-
Kapitola 01.indd 19
30.4.2008 9:28:46
20
Kapitola 1 – Tři vrstvy webu
striktivními zásadami IT divize jejich společnosti, jež je nutí, aby používali starší verze prohlížečů (popř. používají prohlížeče, ve kterých mají určité funkce – jako je JavaScript – vypnuté). Uživatelé, kteří špatně vidí, často stránky prohlížejí pomocí nějaké čtečky obrazovky (screen reader) nebo pomocí speciálního programu zvětšujícího obsah obrazovky. Pro takové uživatele může být váš brilantní vizuální design spíše překážkou než pomocí. Někteří uživatelé váš web ani nenavštíví, protože dají přednost tomu, aby si jeho obsah přečetli pomocí RSS kanálu nebo pomocí obdobného formátu (pokud jim něco takového nabízíte). Až nastane vhodná chvíle vytvořit takové kanály, budete moci těmto uživatelům odeslat obsah HTML bez veškerého harampádí v podobě JavaScriptu nebo CSS. Klíčem k tomu, aby vás web dokázal zaujmout co nejširší okruh návštěvníků, je přemýšlet o webu v termínech tří vrstev, které prakticky odpovídají třem druhům kódu, o nichž jsem se zmínil výše. Tyto vrstvy jsou graficky znázorněné na obrázku 1.2.
Obrázek 1.2. Tři vrstvy webu. Když budujeme web, postupujeme těmito vrstvami zdola nahoru: 1. Začneme tím, že vyprodukujeme obsah ve formátu HTML. To je základní vrstva, kterou by měli být schopni vidět všichni návštěvníci vašeho webu, bez ohledu na to, jaký druh či verzi prohlížeče používají. 2. Když máme hotovou základní vrstvu, můžeme se soustředit na to, aby web vypadal lépe, což uděláme tím, že pomocí CSS přidáme vrstvu prezentačních informací. Web nyní bude vypadat pěkně u těch uživatelů, u nichž je možné zobrazovat styly CSS. 3. A nakonec můžeme s JavaScriptem zavést dodatečnou vrstvu interaktivity a dynamického chování (behavior), takže váš web se bude snadněji používat v prohlížečích s podporou JavaScriptu. Udržíte-li kódy HTML, CSS a JavaScriptu vzájemně od sebe oddělené, nepochybně pak zjistíte, že je mnohem snadnější zajistit, aby vrstva obsahu zůstala čitelná i v takových prohlížecích prostředích, v nichž vrstva prezentace (a/nebo vrstva chování) nejsou funkční. Tento přístup "start na dně" k webovému designu je v branži známý jako progresivní vylepšování (progressive enhancement).
Kapitola 01.indd 20
30.4.2008 9:28:47
Začínáme s JavaScriptem
21
Podívejme se nyní na jednotlivé vrstvy samostatně, abyste si mohli lépe uvědomit, jakým způsobem je nejlépe od sebe navzájem oddělit.
Obsah s HTML Všechno, co je potřeba k tomu, aby se dal přečíst a pochopit obsah webové stránky, patří do kódu HTML dané stránky – nic víc, nic míň. Tak prosté to je. Weboví designéři sami sobě přivodí trable, když zapomenou na princip K.I.S.S.3 a cpou do svého HTML kódu informace, které nelze označit za obsah, nebo když přesouvají část obsahu stránky do kódu CSS nebo JavaScriptu. Běžným příkladem informace, která není obsahem, a přitom se často cpe do stránek, je prezentační HTML kód. Jedná se o kód, který popisuje, jak má vypadat obsah při svém zobrazování v prohlížeči. Patří sem staromódní značky HTML, jako jsou <b>, <i>, <u>, <tt> a <font>: <p>Ať děláte cokoliv, <a href="666.html"><font <font color="red"> color="red">neklikejte na tomto odkazu</font></a>!</p>
Může mít také formu inline CSS aplikovaného pomocí atributu style: <p>Ať děláte cokoliv, <a href="666.html" style="color: red;" red;">neklikejte na tomto odkazu</a>!</p>
Prezentační kód dále může obsahovat utajenou hanbu mnoha webových designérů s dobrými úmysly – styly CSS, které jsou aplikovány v HTML s prezentačními názvy tříd: <p>Ať děláte cokoliv, <a href="666.html" class="red" class="red">neklikejte na tomto odkazu</a>!</p>
Poznámka – prezentační názvy tříd? Jestliže vám připadá poslední příklad v pořádku, nejste sami; rozhodně to ale není dobrý postup. Usoudíte-li později, že odkaz by byl lepší žlutý, budete muset buď aktualizovat název třídy a styly CSS, které se k ní vztahují, nebo se smířit s tím (což je dost trapné), že budete mít třídu pojmenovanou "red" (červená), jež ve skutečnosti styluje žlutě. Z toho byste měli začít žloutnout – ach, promiňte, červenat!
Místo toho, abyste prezentační informace vkládali do kódu HTML, měli byste se soustředit na důvod takové akce. Například – proč chcete zobrazit nějaký odkaz jinou barvou. Je daný odkaz opravdu důležitý? Co kdybyste ho obklopili značkou popisující zdůraznění, které mu chcete udělit: <p>Ať děláte cokoliv, <em> <em><a href="evil.html">neklikejte na tomto odkazu</a></em> </em>!</p>
3
Keep It Simple, Stupid, neboli "dělej to jednoduše, idiote!"
Kapitola 01.indd 21
30.4.2008 9:28:47
22
Kapitola 1 – Tři vrstvy webu
Ale co když má daný odkaz sloužit jako nějaké upozornění? HTML nemá značku, která by popisovala upozornění, nicméně můžete použít takový název třídy CSS, který bude označovat tento druh informace: <p>Ať děláte cokoliv, <a href="evil.html" class="warning" class="warning">neklikejte na tomto odkazu</a>!</p>
Takový přístup se dá samozřejmě přehnat. Např. někteří designéři chybně považují značky jako je <h1> za prezentační a pokoušejí se takový prezentační kód odstranit ze svého kódu HTML: <p class="heading">Záhlaví, když mám krizi identity</p>
Prezentační informace, které máte opravdu držet mimo dokument, jsou zejména písmo, velikost písma a barva, v nichž se má záhlaví zobrazit. Skutečnost, že kus nějakého textu je záhlaví, takže tvoří část obsahu, by se rozhodně měla odrazit v kódu HTML. Takže tento kód je v pořádku: <h1>Záhlaví, když mám mír v duši</h1>
Stručně řečeno – HTML by se mělo používat pro všechno, co vyjadřuje význam, neboli sémantiku obsahu ve stránce. Důsledně byste se měli vyvarovat popisů, jak má obsah vypadat. Experti na webové standardy nazývají takový HTML kód, který popisuje význam, jako sémantické značkování. Pokud používáte sémantické značkování, jsou soubory HTML samy o sobě smysluplnými dokumenty. Lidé, kteří z nějakého důvodu nemohou vaše dokumenty číst tak, že si je prohlížejí v typickém webovém prohlížeči, budou schopni se s nimi seznámit jinak. Například lidé, kteří velmi špatně vidí, si budou moci nechat stránku přečíst nahlas nějakým pomocným softwarem, například nějakou čtečkou obrazovky. Čím jasněji bude kód HTML popisovat význam obsahu, tím srozumitelnější bude pro ty, kteří pro jeho přečtení použijí takové smyslové nástroje. Nejlepší ze všeho je ale to, že sémantické značkování vám umožňuje aplikovat nové styly (pro prezentaci) a interaktivní funkce (chování), aniž byste museli v kódu HTML provádět velké množství změn (pokud vůbec nějaké!).
Prezentace s CSS Je zřejmé, že pokud má být obsah stránky kompletně obsažen uvnitř svého kódu HTML, jeho styl – neboli prezentace – by měl být plně definován v kódu CSS, který se aplikuje na stránku. Když už jste si dali takovou práci, abyste měli HTML kód bez prezentačního kódu a sémanticky bohatý, byla by hanba pokazit takový soubor tím, že ho zaplníte kousky CSS. Jak patrně víte, styly CSS se dají aplikovat na webové stránky trojím způsobem:
Inline styly. <a href="evil.html" style="color: red;" red;">
Inline styly jsou lákavé z důvodů, které jsem už vysvětlil výše: styly můžete aplikovat na obsah hned, když ho vytváříte, aniž byste museli přehodit rychlost a editovat oddělený stylový
Kapitola 01.indd 22
30.4.2008 9:28:47
Začínáme s JavaScriptem
23
předpis. Ale jak už jste se dozvěděli v předchozí sekci, měli byste se snažit těmto přímým stylům vyhýbat jako čert kříži, chcete-li udržet kód HTML maximálně smysluplný.
Vložené styly. <style type="text/css"> .warning { color: red; } </style> ... <a href="evil.html" class="warning" class="warning">
Vložené styly sice zachovávají přehlednost značkování, nicméně takové styly jsou svázány s jediným dokumentem. Ve většině případů chcete své styly sdílet na mnoha stránkách vašeho webu, takže je nejlepší opustit i tento přístup.
Externí styly. <link rel="stylesheet" href="styles.css" /> ... <a href="evil.html" class="warning" class="warning">
styles.css .warning { color: red; }
Externí styly jsou tou správnou cestou, kterou je potřeba preferovat, protože umožňují sdílet styl mezi více dokumenty, snižují objem kódu, který musí prohlížeč stáhnout, a v neposlední řadě umožňují změnit vzhled webu, aniž byste si museli špinit ruce editací HTML kódu. Ale tohle všechno přece už dávno víte, že? Tohle má být ostatně kniha o JavaScriptu, takže si pojďme pohovořit o tom, jak dostanete na vaše stránky JavaScript.
Chování s JavaScriptem Podobně jako u CSS, i JavaScript se dá do webových stránek přidávat mnoha způsoby:
Kód JavaScriptu se dá vložit přímo do obsahu HTML stránky: <a href="evil.html" onclick="sem přijde kód JavaScriptu" JavaScriptu">
Kód JavaScriptu se také dá vložit na začátek HTML dokumentu – do značky <script>: <script type="text/javascript"><!--//--><![CDATA[//><!-sem přijde kód JavaScriptu //--><!]]></script>
Kapitola 01.indd 23
30.4.2008 9:28:47
24
Kapitola 1 – Tři vrstvy webu
... <a href="evil.html" class="warning" class="warning">
Poznámka – CDATA? Pokud se divíte, co znamená ta hatmatilka před značkou <script> a před značkou </script>, tak vězte, že s její pomocí legitimně vložíte JavaScript do XHTML dokumentu, aniž byste tím popletli ty webové prohlížeče, které nerozumí jazyku XHTML (jako je např. Internet Explorer). Pokud vaše stránky obsahují HTML (ne XHTML), vystačíte s mnohem jednodušší syntaxí: <script type="text/javascript"> sem přijde kód JavaScriptu </script>
Kód JavaScriptu vložíte do samostatného souboru a pak v dokumentech HTML uvedete odkaz na tento soubor vždy, když to potřebujete: <script type="text/javascript" src="script.js"></script> ... <a href="evil.html" class="warning">
script.js (výňatek) sem přijde kód JavaScriptu
Hádejte, kterou z metod máte používat? Pokud píšete JavaScript, který vylepšuje použitelnost webových stránek, který neznečišťuje HTML dokumenty, na něž se aplikuje, který nezavírá dveře uživatelům, kteří mají ve svých prohlížečích JavaScript vypnutý, a který nenarušuje jiný kód JavaScriptu, jenž by se mohl aplikovat na tutéž webovou stránku, pak vězte, že se jedná o tzv. nevtíravé skriptování (unobtrusive scripting). Bohužel – i když mnozí profesionální weboví vývojáři mají povědomí o výhodách, které získají, budou-li svůj kód CSS udržovat v samostatných souborech, pořád se najde dost kódu JavaScriptu vloženého přímo do HTML stránky. Když vám v této knize ukážeme správnou cestu, jak používat JavaScript, věříme, že napomůžeme tomu, aby se tato nepříjemná skutečnost změnila.
Správná cesta Takže – jak moc je všechna tahle látka důležitá? Proč se ptáme? Inu, lidé budují weby se smíchaným kódem HTML, CSS a JavaScriptem už léta, přičemž většině lidí brouzdajících po webu takové webové stránky fungují zcela bez problémů. Ovšem proto, že v této knize se vás chystáme naučit JavaScript, je velmi důležité, abyste se jej rovnou naučili používat tím správným způsobem. JavaScript je jednoznačně nejmocnější ze všech tří
Kapitola 01.indd 24
30.4.2008 9:28:47
Začínáme s JavaScriptem
25
jazyků, které používáte při tvorbě designu webových stránek, a jako takový vám poskytuje naprosto bezprecedentní volnost, jak kompletně všechno zpackat. Jeden příklad z mnoha. Máte-li JavaScript rádi, opravdu rádi, můžete zajít až tak daleko, že umístíte úplně všechno – tedy obsah, prezentaci a chování – do kódu JavaScriptu. Už jsem to viděl na vlastní oči, a není to nic pěkného (zejména v případě, kdy je použit prohlížeč, který má JavaScript vypnutý, nebo jej vůbec nepodporuje). Ještě více vypovídající je fakt, že JavaScript je jediný z těchto tří jazyků, který je tak schopný, že může způsobit, že prohlížeč uživateli jednoduše "zamrzne", takže nebude vůbec reagovat4. Ve zbývající části knihy budeme tudíž maximálně usilovat o to, abychom vám neustále ukazovali správnou cestu, jak používat JavaScript. Nejenom proto, že pak budete mít kód úhledný, ale také kvůli tomu, že to napomáhá, aby web pracoval tak, jak se od něho očekává (tzn. aby zpřístupnil svůj obsah co největšímu počtu lidí, bez ohledu na to, jaký webový prohlížeč se rozhodli používat).
Knihovny JavaScriptu Jak už jsem zmínil, oddělení různých druhů kódu přináší mnoho výhod. Jednou z nich je, že kód, který jste napsali pro jeden web, můžete snadno opětovně využít pro jiné weby. Někteří velcí příznivci JavaScriptu (od této chvíle se na ně budeme odkazovat jako na "lidi") si udělali čas na to, aby sestavili obrovské knihovny (libraries) užitečného, nevtíravého kódu JavaScriptu, které si můžete stáhnout a zdarma používat ve vašich webech. V knize budujeme všechny příklady od začátku. To znamená, že veškerý kód JavaScriptu, který budete k těmto příkladům potřebovat, najdete zde, na stránkách knihy. Protože ve skutečném světě není vždy možné postupovat tímto způsobem, a protože knihovny se velmi rychle staly významnou součástí světa JavaScriptu, podíváme se také, jak se pracuje s některými populárními knihovnami JavaScriptu. V této knize budeme používat následující knihovny:
4
Prototype – http://www.prototypejs.org/
script.aculo.us – http://script.aculo.us/
Yahoo! User Interface Library, YUI – http://developer.yahoo.com/yui/
Dojo – http://dojotoolkit.org/
jQuery – http://jquery.com/
MooTools – http://mootools.net/
Názornou ukázku uvidíte v kapitole 7.
Kapitola 01.indd 25
30.4.2008 9:28:47
26
Kapitola 1 – Tři vrstvy webu
Varování – všechny knihovny nejsou stejně dobré Dávejte si pozor na weby, na nichž se nabízejí fragmenty kódu JavaScriptu, které stačí zkopírovat pomocí schránky a vložit do vašich webových stránek pro docílení nějakého konkrétního efektu. Existuje velké množství takového zdarma poskytovaného kódu. Jeho kvalita je ovšem rozdílná. Dobrá knihovna je obvykle poskytována ve formě javascriptového souboru .js, který můžete nevtíravě vložit do vašich stránek, takže nemusíte vkládat kód JavaScriptu přímo do HTML kódu. Necítíte-li se dost povolaní, abyste rozhodli, zdali je nějaká konkrétní knihovna JavaScriptu dobrá nebo ne, požádejte o radu na fórech vývojářského serveru interval.cz5, nebo se prostě spokojte pouze s knihovnami zmiňovanými v této knize, protože ty všechny jsou velmi dobré.
Začněte! Dost bylo kázání – tuto knihu jste si pořídili proto, abyste se naučili JavaScript, je to tak? (Jestliže tomu tak není, obávám se, že asi budete trochu zklamaní.) Čistý a přehledný kód HTML i CSS je sice velmi pěkný, nicméně nyní je čas skočit rovnýma nohama přímo do třetí vrstvy webů: chování. Otočte několik stránek a hned narazíte na skvělý (a nevtíravý) JavaScript.
5 http://interforum.interval.cz
Kapitola 01.indd 26
30.4.2008 9:28:47
KAPITOLA 3 Přístup k dokumentu Kdyby JavaScript neměl po ruce nějaký dokument, neměl by žádnou možnost, jak se předvést. Právě HTML dokument tvoří ono hmatatelné rozhraní, jehož prostřednictvím se JavaScript dostává ke svým uživatelům. Tento vztah znamená, že je životně důležité, aby mohl JavaScript přistupovat k jakékoliv části dokumentu, manipulovat s ní a případně ji i vytvořit. Pro tyto potřeby vytvořilo konsorcium W3C tzv. objektový model dokumentu (DOM, Document Object Model), což je systém, jehož prostřednictvím mohou skripty ovlivňovat dokument. Tento systém umožňuje JavaScriptu nejenom měnit strukturu dokumentu, ale též přistupovat ke stylům dokumentu a měnit jeho vzhled. Chcete-li převzít kontrolu nad vašimi rozhraními, musíte nejprve zvládnout DOM.
Objektový model dokumentu – mapování HTML Když se do prohlížeče stáhne nějaký dokument HTML, musí prohlížeč to, co je v podstatě jediným dlouhatánským řetězcem, převést na webovou stránku. Aby to mohl udělat, musí rozhodnout, které části jsou odstavce, jaké části jsou záhlaví, které části jsou text atd. Aby nebozí programátoři JavaScriptu nemuseli dělat totéž, prohlížeč uloží interpretaci kódu HTML jako strukturu objektů JavaScriptu, které se říká objektový model dokumentu (Document Object Model, neboli DOM). V tomto modelu se každý prvek z HTML dokumentu stane objektem. Totéž se stane se všemi atributy a texty. JavaScript pak může ke všem těmto objektům přistupovat nezávisle, pomocí zabudovaných funkcí, které umožňují za pochodu snadno najít a změnit to, co potřebujete. V důsledku toho, jak se HTML píše – jako hierarchie vnořovaných prvků vyznačených otevírající a uzavírající značkou – DOM sice vytvoří pro každý prvek jiný objekt, nicméně propojí každý objekt prvku s prvkem, který ho obklopuje (tzv. rodičovský prvek). Tím se mezi prvky vytvoří explicitní vztah rodič-potomek, což poskytuje vizualizaci DOM v podobě stromové struktury. Mějme například tento kód HTML:
Kapitola 03.indd 63
30.4.2008 9:29:15
64
Kapitola 3 – Přístup k dokumentu
<!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" lang="en-US"> <head> <title>DOMinance JavaScriptu</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <h1> DOMinance JavaScriptu </h1> <p> Potřebujete-li pomoci se svým JavaScriptem, možná byste si měli přečíst nějaké články na stránkách <a href="http://www.danwebb.net/" rel="external">Dan Webb</a>, <a href="http://www.quirksmode.org/" rel="external">PPK</a> a <a href="http://adactio.com/" rel="external">Jeremy Keith</a>. </p> </body> </html>
Nad prvky namapovanými v DOM se nejsnadněji rozumuje tehdy, pokud je chápete jako stromovou strukturu, která je znázorněna na obrázku 3.1.
Obrázek 3.1. Každý prvek ve stránce HTML má v DOM propojení na svého rodiče. Pokud se má pro nějaký HTML dokument vytvořit DOM, reprezentuje se každý prvek v dokumentu tím, co je obecně známo jako uzel (node). Pozice konkrétního uzlu ve stromu DOM je určena jeho rodičovským uzlem a dceřinými uzly (uzly přímých potomků).
Kapitola 03.indd 64
30.4.2008 9:29:20
Začínáme s JavaScriptem
65
Uzly prvků se rozpoznávají podle svých názvů prvků (head, body, h1 atd.), nicméně ty samozřejmě nemusejí být jedinečné. Pokud nedodáte nějakou identifikační charakteristiku – jako je například atribut id – bude jeden uzel odstavce vypadat stejně jako ostatní. Existuje jeden speciální uzel, který je v dokumentu obsažen vždy, bez ohledu na to, jaký má dokument vlastně obsah. Sídlí vždy na vrcholu stromu a říká se mu uzel dokumentu (document node). Pokud toto vezmeme v potaz, získáme přesnější reprezentaci DOM (viz obrázek 3.2).
Obrázek 3.2. Strom DOM, včetně uzlu dokumentu. Jedním typem uzlů jsou uzly prvků (element nodes), tj. uzly, které reprezentují prvky HTML. Definují většinu struktury DOM, ovšem skutečný obsah dokumentu je obsažen ve dvou dalších typech uzlů – v textových uzlech a v uzlech atributů.
Textové uzly Všechno z kódu HTML, co není obsaženo ve špičatých závorkách, se bude v DOM interpretovat jako textový uzel (text node). Z hlediska struktury se s textovými uzly zachází téměř stejně jako s uzly prvků – sídlí v téže stromové struktuře a dá se k nim dostat stejně jako k uzlům prvků. Nemohou mít ovšem potomky. Pokud se ještě jednou zamyslíme nad příkladem HTML uvedeným výše a přidáme do naší vizualizace DOM textové uzly, bude strom mnohem rozsáhlejší, jak ilustruje obrázek 3.3.
Kapitola 03.indd 65
30.4.2008 9:29:20
66
Kapitola 3 – Přístup k dokumentu
Obrázek 3.3. Kompletní strom DOM, včetně textových uzlů. Přestože textové uzly vypadají velmi podobně jako ostatní, každý z nich má svou vlastní hodnotu, v níž je uložený skutečný text, který je reprezentován tímto uzlem. Takže hodnota textového uzlu uvnitř prvku title je v našem konkrétním případě "DOMinance JavaScriptu."
Poznámka – textové uzly mohou produkovat i prázdné znaky Kromě viditelných znaků obsahují textové uzly též neviditelné znaky, jako jsou např. znaky pro nový řádek nebo zarážky tabulátoru. Jestliže kód odsazujete, aby byl čitelnější (což my v této knize činíme), každý z těchto znaků pro konec řádku nebo zarážku, jimiž oddělujeme značky nebo text, bude zařazen do nějakého textového uzlu. To znamená, že můžete mít nějaké dodatečné textové uzly mezi sousedícími prvky, nebo nějaké prázdné znaky navíc na začátku nebo na konci textového uzlu. Prohlížeče zpracovávají tyto uzly prázdných znaků (whitespace nodes) odlišně, a právě tato variabilita při analýze DOM je důvodem, proč musíte být pečliví a opatrní, pokud se chcete v DOM spoléhat na počet uzlů (nebo na jejich pořadí).
Uzly atributů Protože uzly prvků a textové uzly zahrnují HTML značky a text, jediná další informace, kterou je ještě potřeba brát v úvahu pro DOM, jsou atributy. Ačkoliv na první pohled vypadají atributy jako části prvku (a jistým způsobem také jsou), ve skutečnosti zabírají svůj vlastní typ uzlů, který se příznačně nazývá uzly atributů (attribute nodes). Každý ze tří hypertextových odkazů (tedy prvků a) se v naší ukázce DOM dá vizualizovat pomocí uzlů atributů znázorněných na obrázku 3.4.
Kapitola 03.indd 66
30.4.2008 9:29:20
Začínáme s JavaScriptem
67
Obrázek 3.4. Atributy href a rel, které jsou reprezentovány v DOM jako uzly atributů. Uzly atributů jsou vždy připojeny k uzlu prvku, ale nezapadají do struktury DOM tak, jako uzly prvků a textové uzly – nezapočítávají se do dceřiných uzlů prvku, k němuž jsou připojeny. Kvůli tomu se pro práci s uzly atributů používají jiné funkce – probereme je v kapitole později. Jak jste viděli z výše prezentovaných obrázků, DOM se velmi rychle stane složitým (a to i tehdy, když se jedná o hodně jednoduchý dokument), takže budeme potřebovat nějaké pořádné nástroje, abychom mohli identifikovat části, které potřebujeme, a uměli s nimi dobře manipulovat. Na tuto problematiku se podíváme hned teď.
Přístup k uzlům, s nimiž chcete něco dělat Když jsme se dozvěděli, jak je DOM strukturovaný, dostali jsme jeden dobrý nápad. A to konkrétně ten, že by bylo vhodné uspořádat věci, k nimž chceme přistupovat. Každý uzel – ať už je to uzel prvku, textový uzel nebo uzel atributu – obsahuje informace, na jejichž základě ho můžeme identifikovat, nicméně by asi nebylo to pravé ořechové, kdybychom pokaždé museli projít všechny uzly v dokumentu, abychom našli ty, s nimiž chceme pracovat. S prvkem se prostřednictvím DOM manipuluje podobným způsobem, jako se aplikují styly CSS na konkrétní prvek. Obě tyto úlohy jsou založeny na této všeobecné předloze: 1. Specifikovat prvek, nebo skupinu prvků, které chcete ovlivnit. 2. Specifikovat efekt, který na ně chcete aplikovat. Přestože jsou způsoby, jimiž v obou technologiích manipulujeme s prvky, velmi odlišné, procesy, jimiž nacházíme prvky, se kterými chceme pracovat, jsou naopak pozoruhodně podobné.
Vyhledání prvku podle ID Nejpřímější cesta k prvku vede přes jeho atribut id. Jedná se o nepovinný HTML atribut, který se dá přidat k jakémukoliv prvku na stránce, ovšem s tím omezením, že každé ID, jež použijete, musí být v rámci daného dokumentu jedinečné.
Kapitola 03.indd 67
30.4.2008 9:29:21
68
Kapitola 3 – Přístup k dokumentu
<p id="jedinecnyPrvek"> ... </p>
Zamýšlíte-li hledat prvky podle ID, uvědomte si, že tato snaha je založena na někdy nesnadno splnitelném předpokladu: že prvek, který chcete najít, má přiřazeno příslušné ID. Někdy bude takový předpoklad znamenat, že prvně budete muset strávit se svým kódem HTML nějakou tu chvilku, abyste se přesvědčili (nebo zajistili), že požadovaný prvek má skutečně přiřazeno nějaké ID. V některých případech se ID přirozeně objeví v HTML kódu jako součást sémantické struktury dokumentu. Pokud prvek má dvě ID, pomocí JavaScriptu jej naleznete až neobyčejně snadno. Pokud se chcete na konkrétní prvek odkázat v CSS, použijte selektor ID začínající na #: #jedinecnyPrvek {
1
color: blue; 2 }
Pokud to máme přeložit, tento kód říká následující. 1. Najít prvek s ID jedinecnyPrvek. 2. Nastavit jeho barvu na modrou. CSS je hodně kompaktní jazyk. JavaScript až tak ne. Takže v JavaScriptu se na prvek s nějakým ID odkazujete prostřednictvím metody getElementById, která je dostupná z uzlu document. Jako argument přebírá řetězec, přičemž najde prvek, který obsahuje tento řetězec v podobě ID. Já osobně chápu metodu getElementById jako takového ostřelovače, který umí v daném okamžiku zasáhnout pouze jeden jediný prvek. Jinak řečeno, tato metoda je velmi úzce zaměřená. Představte si například, že náš dokument obsahuje následující kód HTML: <h1> Sniper (1993) </h1> <p> V tomto mistrovském filmu hraje <a id="berenger" href="/name/nm0000297/">Tom Berenger</a> vojáka USA, který operuje v panamské džungli. </p>
Pomocí následujícího kódu můžeme získat odkaz na prvek HTML s identifikátorem berenger (a to bez ohledu na to, o jaký typ prvku se vlastně jedná): var target = document.getElementById("berenger" document.getElementById("berenger");
Proměnná target se nyní odkazuje na uzel DOM prvku a, který obklopuje jméno Tom Berenger. Dále předpokládejme, že toto ID jsme přesunuli k nějakému jinému prvku: <h1 id="berenger" id="berenger">
Kapitola 03.indd 68
30.4.2008 9:29:21
Začínáme s JavaScriptem
69
Sniper (1993) </h1> <p> V tomto mistrovském filmu hraje <a href="/name/nm0000297/">Tom Berenger</a> vojáka USA, který operuje v panamské džungli. </p>
Pokud bychom nyní vykonali stejný kód JavaScriptu, odkazovala by se proměnná target na jiný prvek – v tomto případě na prvek nadpisu h1. Jakmile máte k dispozici odkaz (referenci) na uzel prvku, můžete o něm získávat informace, nebo modifikovat jeho obsah prostřednictvím mnoha nativních vlastností a metod. Při práci s touto knihou prozkoumáte mnohé z těchto metod a vlastností. Pokud se chcete pokusit získat nějaké informace o prvku, který jste právě našli, využijte jednu nebo několik nativních vlastností uzlu prvku. Jednou z těchto vlastností je nodeName, která sděluje přesný název značky uzlu, na který jste se odkázali. Chcete-li zobrazit název značky, která byla zachycena metodou getElementById, použijte tento kód: var target = document.getElementById("berenger"); alert(target.nodeName nodeName);
Následně se objeví okno, v němž se vypíše název značky, jak to vidíte na obrázku 3.5.
Obrázek 3.5. Zobrazení názvu značky prostřednictvím vlastnosti nodeName. Pokud neexistuje prvek s konkrétním ID, které jste použili pro hledání, getElementById nevrátí odkaz na uzel – vrátí hodnotu null. To je speciální hodnota, která obvykle indikuje, že něco chybí. V podstatě vyjadřuje nepřítomnost objektu tam, kde by za normálních okolností měl být. Pokud si nejste jisti, zdali dokument obsahuje prvek s konkrétním ID, který hledáte, nejbezpečnější je zkontrolovat, zdali metoda getElementById skutečně vrátila objekt uzlu, protože když provádíte operace nad hodnotou null, většina operací skončí tím, že program oznámí chybu a přestane se vykonávat. Tato kontrola se snadno udělá pomocí podmínkového příkazu, který ověří, zdali odkaz vrácený z getElementById není náhodou null: var target = document.getElementById("berenger"); if (target != null) {
Kapitola 03.indd 69
30.4.2008 9:29:21
70
Kapitola 3 – Přístup k dokumentu
alert(target.nodeName); }
Vyhledávání prvků podle názvu značky Lokalizovat prvky podle jejich ID je vynikající technika, chcete-li modifikovat v daném čase pouze jediný prvek. Chcete-li však vyhledat celou skupinu prvků, je tou pravou metodou getElementsByTagName. Jejím ekvivalentem v CSS je selektor typu prvku: li { color: blue; }
Na rozdíl od metody getElementById se metoda getElementsByTagName může vykonat jako metoda jakéhokoliv uzlu prvku – nejčastěji se ovšem volá s uzlem document. Mějme následující dokument: <!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" lang="en-US"> <head> <title>Lokátor názvu značky</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <p> V těle tohoto dokumentu jsou tři různé typy prvků: </p> <ul> <li> odstavec </li> <li> neseřazený seznam </li> <li> položka </li> </ul> </body> </html>
Všechny tyto položky seznamu získáme tímto jediným řádkem JavaScriptu:
Kapitola 03.indd 70
30.4.2008 9:29:21
Začínáme s JavaScriptem
71
var listItems = document.getElementsByTagName("li");
Když vykonáváte tento kód, říkáte tím programu, aby prohledal všechny následníky uzlu document, získal všechny uzly, které mají název značky li, a přiřadil tuto skupinu do proměnné listItems. listItems bude obsahovat kolekci uzlů, které se říká seznam uzlů (node list). Seznam uzlů
je objekt JavaScriptu, který obsahuje seznam objektů uzlů v pořadí podle zdroje. V příkladu, který jste právě viděli, mají všechny uzly seznamu uzlů název značky li. Seznamy uzlů se v mnohém chovají podobně jako pole, s nimiž jsme se zabývali ve druhé kapitole, nicméně postrádají některé užitečné metody, jimiž jsou vybavena pole. Obvykle však s nimi můžete zacházet stejně. Protože getElementsByTagName vždy vrátí seznam uzlů ve zdrojovém pořadí, víme, že druhý uzel v seznamu bude skutečně druhým uzlem ve zdrojovém kódu HTML, takže kdybyste se na něj chtěli odkázat, použijete index 1 (vzpomeňte si, že první index v poli je 0): var listItems = document.getElementsByTagName("li"); var secondItem = listItems[1]; secondItem se nyní bude odkazovat na položku seznamu obsahující text "neseřazený seznam".
Seznamy uzlů dále poskytují již známou vlastnost length, takže velmi snadno se dá získat počet uzlů v kolekci – stačí se odkázat na jeho length: var listItems = document.getElementsByTagName("li"); var numItems = listItems.length length;
Pokud toto aplikujeme na náš dokument obsahující tři prvky seznamu, bude mít numItems hodnotu 3. Skutečnost, že na seznam uzlů se odkazuje podobě jako na pole, znamená, že se budou snadno sestavovat cykly, které procházejí všemi uzly seznamu, a jež s každým z nich provedou stejné akce. Chceme-li zkontrolovat, zdali getElementsByTagName opravdu vrátila pouze prvky se stejným názvem značky, můžeme si názvy značek všech uzlů vypsat cyklem for: var listItems = document.getElementsByTagName("li"); for (var i = 0; i < listItems.length; i++) { alert(listItems[i].nodeName); }
Na rozdíl od getElementById vrací metoda getElementsByTagName seznam uzlů i tehdy, když dodaný název značky nemá žádný z prvků. Pak bude mít length tohoto seznamu uzlů hodnotu 0. To znamená, že je bezpečné používat příkazy, které kontrolují length seznamu uzlů, jako je tomu v cyklu výše. Není ovšem bezpečné se přímo odkazovat na nějaký index, pokud jste předtím nezkontrolovali length, abyste se přesvědčili, zdali zadaný index bude platný. Cyklování seznamem uzlů s jeho vlastností length jako podmínkou cyklu se obvykle považuje za nejlepší způsob, jak řešit úlohy tohoto druhu.
Kapitola 03.indd 71
30.4.2008 9:29:21
KAPITOLA 6 Vylepšení formulářů Za posledních deset let se HTML příliš nezměnilo. Od časů, kdy kolem roku 1997 prohlížeče implementovaly změny v HTML 4, zůstala kolekce značek a atributů, které dnes používáme pro tvorbu webových stránek, v podstatě stejná. Ovšem díky postupnému zdokonalování podpory CSS v prohlížečích jsme i s touto limitovanou výbavou značek schopni vytvářet stále bohatší a složitější designy. Podobně jako módní návrháři, kteří se každou sezónu vytasí s převratnými novými módními střihy, barvami a materiály, i styly jsou pořád čerstvé a nové, i když výchozí podkladové modely jsou si strašně podobné. Je tu ovšem jeden aspekt webového designu, u kterého ani CSS nedokážou zakrýt stagnaci jazyka HTML – webové formuláře. Bez ohledu na to, jak je plánujete vylepšit, musíte se v posledních deseti letech u webových formulářů spokojit s docela omezenou sadou ovládacích prvků HTML:
Textová vstupní pole.
Zaškrtávací políčka.
Přepínače.
Rozevírací nabídky a seznamy (také se jim říká roletová menu).
Víceřádkové textové oblasti.
Tlačítka.
Protože je výběr takto omezen, formuláře byly jednou z prvních částí HTML, která přilákala pozornost vývojářů experimentujících s vylepšováním stránek pomocí JavaScriptu. V této kapitole vybudujeme několik vlastních, opětovně využitelných a vylepšených formulářů. Dostanete tak příležitost aplikovat zde mnohé z dovedností, které jste si doposud v této knize osvojili a dokonce se naučíte i několik triků navíc.
Kapitola 06.indd 185
30.4.2008 9:30:07
186
Kapitola 6 – Vylepšení formulářů
Rozšíření DOM HTML Ovládací prvky formuláře nejsou prvky HTML, s nimiž byste pracovali každý den, nehledě na skutečnost, že mají v sobě zabudováno bohatší chování a interaktivitu, než jaká se dá popsat s událostmi click, mouseover, mouseout, focus a blur, nebo s vlastnostmi jako jsou id a classname. Důsledkem je, že kromě standardních vlastností, metod a událostí DOM, s nimiž jsme si už v této knize pohrávali, podporují HTML prvky vztahující se k formuláři ještě celé hejno dalších vlastností a metod, které jsou definovány v samostatné sekci1 standardu DOM. Přehled nejužitečnějších vlastností a metod máte k dispozici v tabulkách 6.1 a 6.2. Ovládací prvky formuláře podporují i několik dalších událostí – jejich přehled je uveden v tabulce 6.3. Tabulka 6.1. Dodatečné metody DOM pro formulářové ovládací prvky HTML. Metoda
Prvek
Popis
blur
input
Odebere focus z klávesnice tomuto formulářovému ovládacímu prvku.
select textarea click
input
Simuluje kliknutí myší na tomto ovládacím prvku.
focus
input
Udělí focus z klávesnice tomuto formulářovému ovládacímu prvku.
select textarea reset
form
Obnoví všechny formulářové ovládací prvky na jejich výchozí hodnoty.
select
input
Vybere textový obsah tohoto ovládacího prvku.
textarea submit
form
Odešle formulář, aniž by spustila událost submit.
V následujících dvou praktických příkladech si pohrajeme s některými – ale nikoliv se všemi – funkcemi DOM, které jsou specifické pro formuláře. Jakmile si uděláte představu o tom, jakou funkcionalitu navíc dokáže JavaScript poskytnout, vraťte se k těmto tabulkám a popřemýšlejte o dalších způsobech, jimiž by mohly tyto nástroje vylepšit vaše webové formuláře. Tabulka 6.2. Dodatečné vlastnosti DOM pro formulářové ovládací prvky HTML.
1
Vlastnost
Prvek
Popis
elements
form
Seznam uzlů, který obsahuje všechny formulářové ovládací prvky ve formuláři.
http://www.w3.org/TR/DOM-Level-2-HTML/
Kapitola 06.indd 186
30.4.2008 9:30:12
Začínáme s JavaScriptem
187
Vlastnost
Prvek
Popis
checked
input
Když je daný ovládací prvek vybrán, má u ovládacích prvků input s type checkbox a radio tato vlastnost hodnotu true.
disabled
button
Když má vlastnost hodnotu true, je ovládací prvek pro uživatele nepřístupný.
input optgroup option select textarea form
button
Odkaz na prvek form, který obsahuje tento ovládací prvek.
input option select textarea index
option
Index tohoto prvku option uvnitř prvku select, který ho obsahuje (začíná se od 0).
options
select
Seznam uzlů obsahující všechny prvky option v této nabídce.
selected
option
true, je-li tato volba aktuálně vybraná, jinak false.
selectedIndex
select
Index aktuálně vybraného prvku option v seznamu (začíná se od 0).
value
button
Aktuální hodnota tohoto ovládacího prvku, jako kdyby se odeslala na server.
input option select textarea
Tabulka 6.3. Dodatečné vlastnosti DOM pro formulářové ovládací prvky HTML. Událost
Prvek
Spustí se, když...
change
input
... ovládací prvek ztratí focus poté, co se jeho hodnota změnila.
select textarea select
input
... uživatel vybral v poli nějaký text.
textarea submit
Kapitola 06.indd 187
form
... uživatel požádal o odeslání formuláře.
30.4.2008 9:30:12
188
Kapitola 6 – Vylepšení formulářů
Příklad – závislá pole Nenuťte uživatele, aby musel vyplňovat všechna pole formuláře. Konkrétní hodnota, kterou uživatel zadá do jednoho pole formuláře, může způsobit, že jiné pole formuláře už bude irelevantní. Proč se spoléhat na uživatele stránky, aby sám rozhodoval, která pole jsou pro něj relevantní a jaká ne, když je možné pomocí vlastnosti disabled, zmíněné v tabulce 6.2, znepřístupnit konkrétní pole, která tak může uživatel bezpečně ignorovat? Zaškrtávací políčko na obrázku 6.1, které je umístěno pod druhým přepínačem, je uživateli přístupné (relevantní) pouze tehdy, když je vybrán tento druhý přepínač. Ve všech ostatních případech je toto zaškrtávací políčko pomocí JavaScriptu vypnuto (znepřístupněno).
Obrázek 6.1. Zaškrtávací políčko bude přístupné jen tehdy, když uživatel vybere druhý přepínač. Nejlepší způsob, jakým se dají implementovat taková závislá pole, závisí (jak obratně řečeno) na konkrétní logice formuláře. Pro potřeby tohoto příkladu ovšem použijeme přístup natolik všeobecný, abyste ho mohli využít i v mnoha jiných situacích. Pro tento účel si nejprve stanovíme a ujasníme následující výchozí předpoklady:
Každý formulář bude mít pouze jednu úroveň závislosti polí (závislé pole nemůže být závislé na nějakém jiném závislém poli).
Závislými poli mohou být pouze prvky input s typem text, password, checkbox nebo radio.
Závislá pole mohou záviset pouze na prvcích input těchto typů.
Závislá pole následují v dokumentu okamžitě za poli, na nichž jsou závislá.
Závislá pole budou obsažena v prvcích label.
Nyní se podívejte, jak bude vypadat kód nejenom pro formulářové pole typu přepínač, ale také pro formulářové pole typu zaškrtávací políčko, které je závislé na tomto přepínači: dependentfields.html (výňatek). <div>
Kapitola 06.indd 188
30.4.2008 9:30:12
Začínáme s JavaScriptem
189
<label for="ncc1701"> <input type="radio" name="whichenterprise" value="ncc1701" id="ncc1701" /> USS Enterprise NCC-1701 (třída Constitution) </label> <label for="ncc1701refit" class="secondary"> <input type="checkbox" class="dependent" name="ncc1701refit" id="ncc1701refit" value="ncc1701refit" disabled="true" /> Po opravě </label> </div>
Připomínám, že zaškrtávací políčko (checkbox) má třídu (class) dependent – takto specifikujeme, že zaškrtávací políčko je závislé na poli, které je v kódu před ním. Kdyby měl náš přepínač více závislých polí, každé z nich by mělo třídu dependent. Když se toto značkování předá prohlížeči, v němž je JavaScript vypnutý, budou závislá pole formuláře pořád přístupná pro uživatele. Náš skript začleníme do objektu, který nazveme DependentFields: dependentfields.js (výňatek) var DependentFields = { init: function() { ... }, ... }; Core.start(DependentFields);
Práci na našem skriptu zahájíme tím, že napíšeme hlavní funkce, které budou podle potřeby zpřístupňovat a znepřístupňovat příslušné pole formuláře: dependentfields.js (výňatek) disable: function(field)
{ field.disabled disabled = true; Core.addClass(field, "disabled"); Core.addClass(field.parentNode, "disabled"); }, enable: function(field) { field.disabled disabled = false;
Kapitola 06.indd 189
30.4.2008 9:30:12
190
Kapitola 6 – Vylepšení formulářů
Core.removeClass(field, "disabled"); Core.removeClass(field.parentNode, "disabled"); },
Dost jednoduché, že? Obě funkce začínají tím, že nastaví vlastnost disabled pole. První funkce se aplikuje na formulářové pole s třídou disabled a na prvek, který jej obsahuje. Druhá funkce pak odebírá tuto třídu z tohoto pole a obsahujícího prvku. Třídu disabled dále použijeme pro ostylování tohoto nepřístupného pole formuláře: dependentfields.css (výňatek) label.disabled { color: #A0A0A0; }
Pokud dáváte přednost technice pozicování za levou hranu obrazovky, kterou jsem detailně popsal ve čtvrté kapitole, klidně ji použijte – pak nepřístupná pole formuláře schováte úplně. Pro vytvoření kódu, který bude volat metody disable a enable, které jsme vám právě ukázali, je možné použít mnoho přístupů. Jako zřejmý se nabízí přístup, ve kterém bychom přidali posluchače události ke každému prvku input, jenž má jedno nebo více závislých polí, a nechali tyto posluchače, aby sami zpřístupňovali a znepřístupňovali závislá pole. I když tento přístup vypadá jako docela evidentní a přirozený, je problematický. Například přepínač nikdy negeneruje užitečnou událost, když přestane být vybrán. Někdy je jedinou cestou, jak dát JavaScriptu najevo, že přepínač už není vybraný, událost click vedlejšího přepínače. Další přístup je založen na tom, že ke každému formuláři na stránce se přidají dva posluchači události, kteří budou dávat pozor na události click a change probublávající z kteréhokoliv pole ve formuláři, přičemž po každé takové události budou aktualizovat stav všech závislých polí ve formuláři: dependentfields.js (výňatek) init: function() { var forms = document.getElementsByTagName("form"); for (var i = 0; i < forms.length; i++) { Core.addEventListener( forms[i], "change", DependentFields.changeListener); Core.addEventListener( forms[i], "click", DependentFields.clickListener);
Abychom těmto posluchačům události trochu usnadnili práci (protože poběží docela často), bude metoda init procházet každý webový formulář na stránce, aby mohla vybudovat seznam závislých polí ve formulářích. Pro každé takové pole si uloží pak jednu referenci na pole, na němž je dané pole závislé:
Kapitola 06.indd 190
30.4.2008 9:30:12
Začínáme s JavaScriptem
191
dependentfields.js (výňatek) var fields = forms[i].getElementsByTagName("input");
1
var lastIndependentField = null; forms[i]._dependents = [];
2
for (var j = 0; j < fields.length; j++) { if (!Core.hasClass(fields[j], "dependent")) 3 { lastIndependentField = fields[j]; 4 } else { if (lastIndependentField) 5 { forms[i]._dependents[forms[i]._dependents.length] = fields[j]; 6 fields[j]._master = lastIndependentField; 7 } } }
Tenhle kód vypadá na první pohled jako dost spletitý, takže mi dovolte, abych ho rozebral: 1. Získáme seznam všech prvků input ve formuláři. 2. Pro formulář vytvoříme vlastní vlastnost s názvem _dependents, do které uložíme seznam všech závislých polí ve formuláři. Na začátku ji pochopitelně inicializujeme na prázdné pole. 3. Pro každé pole ve formuláři zkontrolujeme, zdali je závislé či nikoliv. 4. Pokud se jedná o nezávislé pole, uložíme na něj referenci do proměnné nazvané jako lastIndependentField. 5. Pokud se jedná o závislé pole, ještě jednou zkontrolujeme, zdali jsme opravdu získali referenci na pole, na kterém je toto pole závislé. 6. Do vlastnosti _dependents uložíme referenci na toto závislé pole. 7. A nakonec do vlastní vlastnosti s názvem _master uložíme referenci na pole, na kterém závisí příslušné závislé pole. Když tohle všechno shrneme, kód dodá nejenom seznam všech závislých polí v každém formuláři (form._dependents), ale také referenci z každého závislého pole na to konkrétní pole, na kterém je dané pole zavislé (dependents._master). Metoda init pak pro každý formulář nastaví počáteční stavy všech závislých polí. Protože se jedná o docela složitý proces, napíšeme pro tuto činnost samostatnou metodu updateDependents:
Kapitola 06.indd 191
30.4.2008 9:30:12
192
Kapitola 6 – Vylepšení formulářů
dependentfields.js (výňatek) DependentFields.updateDependents(forms[i]); } },
Protože oba naši posluchači události zahajují stejný proces aktualizace stavů závislého pole, budou oba volat stejnou metodu: dependentfields.js (výňatek) changeListener: function(event) { DependentFields.updateDependents(this); }, clickListener: function(event) { DependentFields.updateDependents(this); }
Nyní už nezbývá nic jiného, než konečně napsat tu veledůležitou metodu updateDependents, která buď zpřístupní, nebo znepřístupní každé závislé pole ve formuláři na základě toho, jaký stav bude mít pole, na němž je dané pole závislé. dependentfields.js (výňatek) updateDependents: function(form) { var dependents = form._dependents; 1 if (!dependents) { return; } for (var i = 0; i < dependents.length; i++) 2 { var disabled = true; 3 var master = dependents[i]._master;
4
if (master.type == "text" || master.type == "password")
5
{ if (master.value.length > 0) { disabled = false; } } else if (master.type == "checkbox" || master.type == "radio")
Kapitola 06.indd 192
6
30.4.2008 9:30:12
Začínáme s JavaScriptem
193
{ if (master.checked) { disabled = false; } } if (disabled)
7
{ DependentFields.disable(dependents[i]); } else { DependentFields.enable(dependents[i]); } } },
Tuto metodu si opět rozebereme krok za krokem: 1. Začneme tím, že si vytáhneme seznam závislých polí formuláře, který nám připravila metoda init. 2. Tento seznam v cyklu projedeme, pěkně jedno závislé pole za druhým. 3. U každého pole na začátku předpokládáme, že bude nepřístupné. Následně si pak vyjasníme, zdali náš předpoklad byl chybný, nebo ne. 4. Abychom to zjistili, podíváme se na pole, na němž je dané pole závislé – potřebnou informaci obdržíme z vlastnosti _master, kterou jsme vytvořili v metodě init. 5. Je-li hlavním polem text nebo password, zkontrolujeme délku (length) hodnoty vlastnosti value. Pokud je větší než nula, závislé pole by nemělo být vypnuté (nepřístupné). 6. Pokud má hlavní pole typ checkbox nebo radio, zkontrolujeme, zdali je políčko zaškrtnuté, resp. zdali je přepínač vybraný (vlastnost checked). Pokud tomu tak bude, závislé pole by nemělo být vypnuté (nepřístupné). 7. Nyní už bezpečně víme, zdali má být závislé pole vypnuté (nepřístupné) či nikoliv, takže zavoláme buď metodu disable, nebo metodu enable, abychom nastavili patřičný stav. A máme to z krku! Náš skript využil celou řadu rozšíření HTML z DOM:
Připravili jsme posluchače události change, kterou generují některé ovládací prvky.
Využili jsme vlastnost disabled, kterou podporují všechny formulářové ovládací prvky, abychom v případě potřeby znepřístupnili závislá pole.
Kapitola 06.indd 193
30.4.2008 9:30:12
KAPITOLA 8 Ajax Pravděpodobně nebude příliš zdrženlivým vyjádření, když řeknu, že Ajax revitalizoval web. Rozhodně je jedním z důvodů, který stojí za opětovně ožívajícím zájmem o JavaScript a je možné, že dokonce zapříčinil, že nyní čtete tuto knihu. Bez ohledu na nadsázky obklopující Ajax, tato technologie dramaticky ovlivnila způsob, jímž lidé mohou komunikovat s webovou stránkou. Schopnost aktualizovat jednotlivé části stránky informacemi ze vzdáleného serveru vám možná nezní jako revoluční změna, nicméně poskytla bezproblémový typ interakce, který jsme v HTML dokumentech postrádali od jejich vzniku. Schopnost vytvářet plynule se aktualizující webovou stránku upoutala velkou měrou představivost jak webových vývojářů, tak i designérů, z nichž spousta přešla k Ajaxu. Výsledkem ovšem byla další generace webových aplikací, které šly průměrnému uživateli pořádně na nervy. Je známo, že každá nová technologie svádí k jejímu nadměrnému používání, a stejně tak tomu bylo s Ajaxem. Když se ovšem Ajax používá citlivě a v rozumné míře, rozhodně pomáhá vytvářet rozhraní, která jsou k uživateli více vstřícnější, přičemž poskytují mnohem pestřejší a příjemnější zážitky. Přestože existuje docela dost "hotových" knihoven JavaScriptu, které nabízejí "kompletní zážitky s Ajaxem", osobně si myslím, že tímto není možné nahradit svobodu, jež přichází společně se znalostmi vztahujícími se k detailnímu principu fungování dané technologie – v tomto případě Ajaxu. Ale už dost povídání a planého filozofování, pojďme si říci více o Ajaxu.
XMLHttpRequest – servírování soust obsahu tak akorát do úst Klíčovou koncepcí Ajaxu je, že informujete prohlížeč, aby obsah nehltal, ale dával si do úst pouze přijatelně velká sousta. Místo celé stránky, kterou možná požadujete, třeba jenom jediný odstavec.
Kapitola 08.indd 257
30.4.2008 9:30:49
258
Kapitola 8 – Ajax
Přestože cestu k funkcionalitě Ajaxu, která by byla použitelná ve všech webových prohlížečích, prosekaly už dříve plovoucí rámce (prvky iframes), aktuální rozmach Ajaxu podnítila až dostupnost objektu XMLHttpRequest ve většině webových prohlížečů. XMLHttpRequest je funkcionalita webového prohlížeče, která umožňuje JavaScriptu zavolat server,
aniž by bylo nutné projít klasickým mechanismem požadavek-stránka. To znamená, že JavaScript může – zatímco se prohlíží daná stránka – provádět na pozadí dodatečné požadavky na server. V podstatě toto umožňuje vytahovat další data ze serveru a následně manipulovat se stránkou pomocí DOM – tedy nahrazovat sekce, přidávat sekce, nebo odstraňovat sekce podle dat, která právě získáváme. Rozdíl mezi normálními požadavky a požadavky Ajaxu ilustruje obrázek 8.1. Normální požadavek stránky
Ajaxový požadavek
Obrázek 8.1. Porovnání normálního požadavku na stránku (kdy se nahradí celá stránka) s požadavkem Ajaxu (kdy se nahradí pouze konkrétní část stránky). Komunikacím se serverem, kdy se nepoužívá mechanismus požadavek-stránka, se říká asynchronní požadavky (asynchronous requests), protože se dají provádět bez toho, aby se přerušila interakce uživatele se stránkou. Normální požadavek na stránku je synchronní v tom smyslu, že prohlížeč čeká na odpověď od serveru, přičemž další interakci povolí až tehdy, až dorazí odpověď. XMLHttpRequest je ve skutečnosti jediným aspektem Ajaxu, který je úplně nový. Všechny ostatní
části interakce Ajaxu – posluchač události, který ji spustí, manipulace DOM, jež aktualizuje stránku atd. – to vše jsme už probrali v předchozích kapitolách knihy. Takže – jakmile budete vědět, jak se vydá asynchronní požadavek, bez nadsázky budete umět vše potřebné.
Vytvoření objektu XMLHttpRequest Internet Explorer 5 a 6 byly prvními prohlížeči, které implementovaly objekt XMLHttpRequest (prostřednictvím objektu ActiveX)1: var requester = new ActiveXObject("Microsoft.XMLHTTP");
Všechny ostatní prohlížeče, které podporují objekt XMLHttpRequest (včetně Internet Exploreru 7) to dělají už bez ActiveX. Objekt požadavku vypadá v těchto prohlížečích takto:
1
Objekt ActiveX je termín společnosti Microsoft pro opětovně využitelnou softwarovou komponentu, která poskytuje zapouzdřenou, opětovně využitelnou, funkcionalitu. V Internet Exploreru poskytují takové objekty za normálních okolností skriptům na straně klienta přístup k všelijaké výbavě operačního systému, jako je systém souborů, nebo – v případě, že se jedná o XMLHttpRequest – k síťové vrstvě.
Kapitola 08.indd 258
30.4.2008 9:30:54
Začínáme s JavaScriptem
259
var requester = new XMLHttpRequest();
Varování – na ActiveX se nemůžete spoléhat V Internet Exploreru 6 a jeho starších verzích byl XMLHttpRequest implementován tak, že pokud uživatel zakázal důvěryhodné (trusted) ovládací prvky ActiveX, stal se objekt XMLHttpRequest nedostupným, i když JavaScript byl povolen. Ačkoliv mnoho lidí zakazuje nedůvěryhodné (untrusted) ovládací prvky ActiveX, zákaz důvěryhodných ovládacích prvků ActiveX už není tak běžný.
Rozdíly mezi dvěma zmíněnými metodami pro vytvoření objektu můžeme snadno uvést v soulad prostřednictvím příkazu try-catch, který automaticky detekuje správný způsob pro vytvoření objektu XMLHttpRequest: try-catch_test.js (výňatek) try { var requester = new XMLHttpRequest();
1
} catch (error)
2
{ try { var requester = new ActiveXObject("Microsoft.XMLHTTP");
3
} catch (error) { var requester = null; } }
S příkazem try se můžete pokusit vykonat blok kódu, ale jakmile cokoliv uvnitř tohoto kódu způsobí chybu, běh programu neskončí, protože se přesune do příkazu catch a vykoná kód, který je uvnitř tohoto příkazu. Jak vidíte z obrázku 8.2, je to hodně podobné struktuře příkazu if-else, ovšem s tím rozdílem, že větvení neurčuje podmínka, ale výskyt nějaké chyby.
Kapitola 08.indd 259
30.4.2008 9:30:55
260
Kapitola 8 – Ajax
Obrázek 8.2. Logická struktura příkazu try-catch. Pro vytváření objektů ActiveX se neobejdeme bez příkazu try-catch, protože test detekce objektu bude indikovat, že ovládací prvky ActiveX jsou dostupné i v případě, kdy je uživatel zakázal (takže skript vygeneruje chybu, až se pokusíte objekt ActiveX vytvořit).
Poznámka – ke škodě už došlo Dojde-li k chybě uvnitř příkazu try, program se nevrátí do stavu, v jakém byl předtím, než se příkaz try vykonal – místo toho okamžitě přejde do příkazu catch. Důsledkem je, že všechny proměnné, které se vytvořily předtím, než došlo k chybě, budou pořád existovat. Jestliže ovšem došlo k chybě v okamžiku, kdy se proměnná přiřazovala, tato proměnná se vůbec nevytvoří.
A zde následuje popis toho, co všechno se bude dít v kódu uvedeném výše: 1. Pokusíme se vytvořit objekt XMLHttpRequest metodou použitelnou ve většině prohlížečů. Bude-li pokus úspěšný, bude proměnná requester novým objektem XMLHttpRequest. Pokud bude objekt XMLHttpRequest nedostupný, kód sice způsobí chybu, nicméně se budeme moci pokusit vytvořit objekt jiným způsobem (v příkazu catch). 2. Příkazy catch zachytávají výjimky, které způsobily, že příkaz try se nezdařil. Výjimka se specifikuje názvem proměnné, který se uvede v závorkách za klíčovým slovem catch a je povinná, protože přiděluje výjimce název (nezáleží na tom, zdali tento název použijete či nikoliv). Výjimce můžete přidělit jakýkoliv název – myslím si, že error je docela zřejmý. 3. Uvnitř příkazu catch se pokusíme vytvořit objekt XMLHttpRequest přes ActiveX. Pokud se to povede, bude requester platným objektem XMLHttpRequest. Jestliže se ale opět nepoda-
Kapitola 08.indd 260
30.4.2008 9:30:55
Začínáme s JavaScriptem
261
ří objekt vytvořit, nastaví druhý příkaz catch proměnnou requester na null. V takovém případě je snadné otestovat, zdali aktuální uživatelský agent podporuje XMLHttpRequest. Pokud to bude nutné, vykoná se nějaký nouzový kód, který nespadá pod Ajax (například to může být normální odeslání formuláře): if (requester == null) { kód pro klienty bez Ajaxu } else { kód pro klienty se zapnutým Ajaxem }
Významné odlišnosti, které se objevují v implementaci objektu XMLHttpRequest v různých webových prohlížečích, naštěstí končí vytvořením tohoto objektu. Všechny základní komunikační metody pro práci s daty se volají prostřednictvím stejné syntaxe – bez ohledu na prohlížeč, kde běží.
Volání serveru Jakmile máme vytvořen objekt XMLHttpRequest, musíme zavolat dvě samostatné metody open a send, abychom byli schopni získávat data ze serveru. Metoda open inicializuje připojení, přebírá dva povinné a několik nepovinných argumentů. Prvním povinným argumentem je typ HTTP požadavku, který chcete odeslat (GET, POST, DELETE atd.). Druhým je pak umístění, z něhož požadujeme data. Například – pokud bychom chtěli použít požadavek GET pro přístup k souboru feed.xml, který se nachází v kořenovém adresáři webu, inicializovali bychom objekt XMLHttpRequest takto: requester.open("GET", "/feed.xml", true);
URL sice může být relativní nebo absolutní, ale kvůli záležitostem týkajícím se bezpečnosti musí cíl sídlit ve stejné doméně jako stránka, která ho požaduje.
Poznámka – pouze HTTP Hodně prohlížečů povoluje volání objektu XMLHttpRequest pouze přes URL s prefixem http:// a https://. Jinak řečeno, pokud si vaše stránky prohlížíte na lokálním umístění prostřednictvím URL s prefixem file://, je možné, že volání objektu XMLHttpRequest nebude povoleno.
Třetím argumentem open je logická hodnota, která specifikuje, zdali je požadavek asynchronní (true), nebo synchronní (false). Synchronní požadavek způsobí, že prohlížeč nebude reagovat až do té doby, dokud nebude požadavek dokončen. To znamená, že v této době není povolena interakce s uživatelem. Asynchronní požadavek se vykonává na pozadí, takže simultánně mohou běžet
Kapitola 08.indd 261
30.4.2008 9:30:55
262
Kapitola 8 – Ajax
jiné skripty, přičemž uživatel může používat prohlížeč obvyklým způsobem. Já doporučuji, abyste vždy používali asynchronní požadavky, jinak riskujete, že prohlížeče uživatelů budou zablokovány při čekání na požadavek, který nefunguje řádně. Metoda open dále poskytuje čtvrtý a pátý argument. Oba jsou nepovinné. Umožňují specifikovat uživatelské jméno a heslo pro potřeby autentizace (obvykle v situacích, kdy chcete přistoupit k URL, která je chráněna heslem). Jakmile jste metodou open inicializovali připojení, metoda send připojení aktivuje a vydá požadavek. Metoda send přebírá jeden argument, který umožňuje odeslat společně s požadavkem POST data, jež jsou zakódována ve stejném formátu, jako když se odesílá formulář: requester.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); requester.open("POST", "/query.php", true); requester.send("name=Clark&email=superman@justiceleague.xmp");
Poznámka – požadovaný Content-Type Prohlížeč Opera požaduje, abyste metodou setRequestHeader nastavili záhlaví Content-Type požadavku POST. Ostatní prohlížeče to sice nepožadují, nicméně se jedná o nejbezpečnější přístup, který byste měli používat u všech webových prohlížečů.
Chcete-li simulovat odeslání formuláře požadavkem GET, musíte explicitně zakódovat názvy a jejich hodnoty do URL metody open a pak vykonat send s argumentem null: requester.open("GET", "query.php?name=Clark&email=superman@justiceleague.xmp", true); requester.send(null);
Internet Explorer nepožaduje, abyste předávali do send nějakou hodnotu, prohlížeče Mozilla ovšem vrátí chybu, nepředáte-li nic, takže proto je v kódu výše uveden argument null. Jakmile jste zavolali metodu send, objekt XMLHttpRequest bude kontaktovat server a získá data, která jste požadovali. V případě, že se jednalo o asynchronní požadavek, funkce, která vytvořila připojení, pravděpodobně dokončí svůj běh během získávání dat. V termínech toku programu se volání XMLHttpRequest hodně podobá volání setTimeout, na které se určitě pamatujete z kapitoly 5. K oznámení toho, že server vrátil odpověď, použijeme obsluhu události. V tomto konkrétním případě potřebujeme zpracovat změny v hodnotě vlastnosti readyState objektu XMLHttpRequest, která specifikuje stav připojení objektu. Může nabývat těchto hodnot:
0 (uninitialized, neinicializováno).
1 (loading, nahráváno).
2 (loaded, nahráno).
Kapitola 08.indd 262
30.4.2008 9:30:55
Začínáme s JavaScriptem
3 (interactive, probíhá dialog).
4 (complete, kompletní).
263
Změny vlastnosti readyState můžeme monitorovat obsluhou událostí readystatechange, které se odpalují při každé změně hodnoty této vlastnosti: requester.onreadystatechange = readystatechangeHandler; function readystatechangeHandler() { Nějaký kód zpracovávající změny hodnoty vlastnosti readyState objektu XMLHttpRequest }
Hodnota readyState se inkrementuje od 0 do 4, přičemž událost readystatechange se spouští při každé inkrementaci. My se ovšem potřebujeme pouze dozvědět, kdy se připojení dokončí (tj. kdy se bude readyState rovnat 4), takže naše funkce bude muset kontrolovat tuto hodnotu. Poté, co se připojení dokončí, budeme muset také zkontrolovat, zdali objekt XMLHttpRequest úspěšně získal data, nebo zdali obdržel nějaký chybový kód, jako je např. 404 (stránka nenalezena). To můžeme určit z vlastnosti status objektu XMLHttpRequest, která obsahuje celočíselnou hodnotu. Hodnota 200 znamená splněný požadavek, takže tuto hodnotu je potřeba zkontrolovat společně s hodnotou 304 (nic se nezměnilo), protože obě indikují úspěšně získaná data. Vlastnost status ovšem může mít hodnotu libovolného kódu HTTP, který může server vrátit, takže asi budete muset napsat několik podmínek, abyste zpracovali i několik dalších kódů. Obvykle ovšem stačí, když specifikujete, co má program podniknout za akce, jestliže byl požadavek neúspěšný: requester.onreadystatechange = readystatechangeHandler; function readystatechangeHandler() { if (requester.readyState == 4) { if (requester.status == 200 || requester.status == 304) { kód zpracovávající úspěšný požadavek } else { kód zpracovávající neúspěšný požadavek } } }
Místo toho, abyste přiřazovali funkci, která je někde definována jako obsluha události readystatechange, můžete přímo (inline) deklarovat novou anonymní (tzn. nepojmenovanou) funkci:
Kapitola 08.indd 263
30.4.2008 9:30:55
264
Kapitola 8 – Ajax
requester.onreadystatechange = function() { if (requester.readyState == 4) { if (requester.status == 200 || requester.status == 304) { kód zpracovávající úspěšný požadavek } else { kód zpracovávající neúspěšný požadavek } } }
Předností této přímé (inline) specifikace funkce zpětného volání readystatechange je to, že objekt requester bude dostupný uvnitř této funkce pomocí uzávěry (closure). Jestliže se obsluha události readystatechange deklaruje samostatně, musíte proskákat několika brankami, chcete-li obdržet referenci na objekt requester uvnitř funkce pro obsluhu události.
Poznámka – XMLHttpRequest není recyklovatelný Přestože objekt XMLHttpRequest povoluje volat metodu open několikrát, každý objekt se dá použít pouze pro jedno volání, protože událost readystatechange se odmítne odpálit znovu, jakmile se readyState změní na 4 (v prohlížečích Mozilla). Takže vždy, když budete chtít získat nějaká data ze serveru, budete muset vytvořit nový objekt XMLHttpRequest.
Práce s daty Jestliže jste vydali požadavek, který skončil úspěšně, je dalším logickým krokem přečíst odpověď serveru. Pro tento účel se dají využít dvě vlastnosti objektu XMLHttpRequest: responseXML
responseText
Do této vlastnosti se uloží strom DOM reprezentující získaná data, ale pouze tehdy, pokud server pro odpověď indikoval content-type rovno text/xml. Tento strom DOM se dá zkoumat a modifikovat pomocí standardních metod a vlastností pro přístup k DOM JavaScriptu, což je téma, které jsme probírali ve třetí kapitole (patří mezi ně getElementsByTagName, childNodes a parentNode). Do této vlastnosti se uloží data odpovědi v podobě jediného řetězce. Jestliže je content-type dat dodaných serverem text/plain nebo text/html, bude to jediná
vlastnost obsahující data. V případě odpovědi s text/xml bude vlastnost obsahovat XML, také v podobě textového řetězce (alternativa k vlastnosti responseXML).
Kapitola 08.indd 264
30.4.2008 9:30:55