document.all a Opera 9

Při tvorbě složitějších javascriptových aplikací občas potřebujete vrátit všechny elementy na stránce. V jedné své aplikaci jsem (v polospánku, rauši či jiném podobném hnutí mysli) použil tuto nebezpečnou konstrukci:

prvky = document.all ? document.all : document.getElementsByTagName('*');

Co hůř, připadlo mi to jako schůdné řešení, instinkty mlčely. Praxe však ukázala své drápky o den později, když jsem aplikace testoval v různých prohlížečích. Deset jich prošlo, ten jedenáctý – Opera 9 – nikoliv. Zkušení javascripteři už si poklepávají na čelo a pro Ty méně zkušené přicházím s vysvětlením.

Ve výše uvedeném kódu testuji prohlížeč na podporu kolekce document.all, kterou představil Internet Explorer ve své čtvrté verzi a kterou také převzali mnohé konkurenční prohlížeče. Tato kolekce má obsahovat všechny prvky na stránce, ale její chování není nikterak závazně popsáno, tzn. ve specifikaci DOM ji nenajdete.

Přesto tuto kolekci podporují všechny tři nejrozšířenější prohlížeče – Explorer, Mozilla/Firefox i Opera. Zatímco podpora u Mozilly je tichá, dotaz if (document.all) vrací hodnotu false, Opera se k podpoře kolekce document.all hrdě hlásí. To znamená, že v Opeře se do proměnné prvky v příkladu nahoře uloží prvky obsažené právě v kolekci document.all. Zde je kámen úrazu.

Opera 9 je důsledná a v této kolekci obsahuje nejen všechny elementy (HTML, HEAD, META, SCRIPT, BODY, P atd.), ale i anonymní textové uzly. Pokud se vyznáte v DOM, víte, o čem mluvím. Pro ostatní drobné zjednodušení – tyto textové uzly se vytvoří všude tam, kde daný element obsahuje libovolná textová data. V elementu <script> jde například o zdrojový kód skriptu, v elementu <p> o text odstavce atd. Takové uzly jsou jiného typu než uzly elementů a nelze s nimi pracovat stejným způsobem, například nenabývají žádné hodnoty metody tagName, která běžně vrací jméno elementu.

Vy však chcete vrátit pouze elementy, textové uzly vás nejspíše nezajímají, proto je vám podobná kolekce k ničemu. Chcete Opeře podstrčit druhý zápis, ten s hvězdičkou a standardní metodou getElementsByTagName. Tady jsem chyboval, když jsem tuto metodu nepoužil jako výchozí. Myslel jsem až příliš na Explorer do verze 5.5, který zápis s hvězdičkou (která říká, že chci vybrat všechny elementy, jedno jakého jména) nedokázal zpracovat. Přitom se nabízí mnohem bezpečnější zápis, a to:

prvky = document.getElementsByTagName('*').length > 0 ? document.getElementsByTagName('*') : document.all;

A to je celé kouzlo.

(Pro pokročilé javascriptaře a pro úplnost dodávám, že při práci s XML dokumenty či fragmenty dokumentů se tato metoda může krutě vymstít a skončit kritickou chybou v prohlížečích, které volání document.all vůbec neznají, v případě, že budeme pracovat s prázdným dokumentem či jeho zlomkem. V takovém případě je jedinou cestou pečlivé testování podpory jednotlivých metod a navrácených výsledků.)

10. 10. 2006, 10.20 | Javascript, AJAX.


Zanechte komentář





Můžete použít Texy! formátování.
Pokud se obsah boxů níže mění, zatímco píšete, potom žádné číslice nevyplňujte. V takovém případě antispam funguje, pouze se prohlížeči nepovedlo skrýt tento box.