Każdy kto programował w JavaScript przyzwyczaił się zapewne do zdarzenia onLoad występującego w momencie załadowania się danej strony WWW. Z reguły wraz z tym zdarzeniem swoje działanie rozpoczynały wszelkie skrypty JS związane z DOM, bo wywołanie ich wcześniej niechybnie skończyłoby się błędem związanym z odwoływaniem do elementu, który jeszcze w DOM nie istnieje.

Dlaczego używać DomReady ?

Nie ma co ukrywać, że w wypadku stron bogatych w grafikę oczekiwanie na wystąpienie zdarzenia onLoad wymagało cierpliwości (wprost proporcjonalnej do ilości grafiki). Na nasze szczęście stworzono zdarzenie DOMContentLoaded - występuje ono w momencie załadowania kompletnego drzewa dokumentu - zatem znacznie wcześniej niż zdarzenie onLoad, bo zdarzenie DOMContentLoaded nie jest zależne od ilości grafiki - w skrajnych wypadkach może więc ono wystąpić kilkanaście sekund przed zdarzeniem onLoad.

Znów ta kompatybilność

Żeby nie było tak słodko jak się niektórym wydaje, to muszę tu wspomnieć o tym co jest największą bolączką JS - jak zwykle wszystko zależy od przeglądarki - zdarzenie DOMContentLoaded zadziała na Firefoksie (i oczywiście wszelkich bazowanych na Gecko przeglądarkach) i Operze (wersje od 9.0 w górę), w wypadku IE trzeba zastosować tą metodę, natomiast Safari i Konqueror wymagają sprawdzania właściwości document.readyState (choć ostatnie wersje Safari wspierają natywnie zdarzenie DOMContentLoaded i kilka innych zdarzeń DOM) - czyli sprawa się ma niewiele lepiej niż w IE. Dociekliwych tego jak to dokładnie działa odsyłam do wpisu Riddle'a, który opisał całość dokładnie - ewentualnie można obejrzeć implementacje w MooTools czy jQuery. Całe szczęście, że ilość przeglądarek zupełnie nie mających szansy na obsługę DOMContentLoaded ociera się o błąd statystyczny (no chyba, że macie dziwną grupę docelową) ;).

Pora więc pokazać jak to się robi w MooTools:

window.addEvent("domready", function(){
    // wszystko tutaj wykona się po załadowaniu DOM
});

Powyższy kod to właściwie jeden z tych fragmentów, który pojawia się bardzo często w każdym skrypcie pisanym z użyciem MooTools, dlatego jak ktoś ma słabą pamięć to warto go sobie gdzieś zachować/powiesić na ścianie/[inna forma wspomagania zawodnej pamięci].

Dlaczego warto stosować DOMContentLoaded ?

Teraz pora na opisanie kilku zastosowań tego cudownego zdarzenia ;)

  • Czasem w życiu bywa tak, że któraś z nowoczesnych przeglądarek podczas renderowania strony coś psuje - o ile w IE mamy do dyspozycji Expressions (tu znów odsyłam do Riddle'a) w Firefoksie mamy ostatecznie do dyspozycji XBL o tyle dla Opery i Safari nie znam żadnych cudownych metod uzdrawiania tego co wyświetli silnik przeglądarki (a może wiecie coś czego ja nie wiem ? Komentarz mile widziany :). Dlatego też wykorzystując obiekt Browser możemy stwierdzić z kim mamy do czynienia (z jaką przeglądarką) i poprawić to i owo, a dzięki zdarzeniu DOMContentLoaded, zmiany pojawią się (z reguły) o wiele wcześniej niż cała strona.
  • Nie muszę chyba nikomu mówić, że możliwość wykonania jakiejś operacji przed załadowaniem całej strony (która może być tylko jedną z podstron na drodze do celu) jest dla użytkownika bezcenna - dlatego dodanie zdarzeń do elementów strony zawsze powinno następować jak najszybciej, tak aby użytkownik mógł być pewien, że widząc jakiś przycisk po jego kliknięciu uzyska wykonanie oczekiwanej operacji zamiast braku jakiejkolwiek reakcji.
  • W pewnych specyficznych sytuacjach (strony statyczne) możemy symulować takie efekty jak wybór stylu strony - wraz z dokumentem ładujemy wspólną część dla wszystkich styli, a wraz ze zdarzeniem DOMContentLoaded analizujemy zawartości ciasteczek (Cookies) i na tej podstawie "doładowujemy" (przydatny tu będzie plugin Assets) dodatkowy, określony przez użytkownika styl. Może całość jest trochę naciągana, ale gdy nie ma żadnego języka server-side pod ręką trzeba sobie jakoś radzić :)

Ostrożność to podstawa

Na koniec jeszcze jedna istotna uwaga związana ze zdarzeniem DomReady w MooTools. Zdarzyło mi się kilka przypadków, kiedy to w IE występowały problemy - było to prawdopodobnie związane z dużym stopniem skomplikowania stron na których występował problem. Okazywało się bowiem, że zdarzenie to występowało przed załadowaniem całego drzewa DOM. Co polecam ? W miarę możliwości podczas procesu tworzenia skryptu bazować na zdarzeniu onLoad, natomiast na sam koniec spróbować je zamienić na zdarzenie DomReady i dokładnie zbadać zachowanie skryptu w IE. Pozwoli to uniknąć błędów, które można powiedzieć biorą się z kosmosu - skrypt "nie widzi" elementów strony, które są załadowane itp.

Podsumowanie

O zdarzeniach w MooTools 1.2 wiemy już właściwie wszystko co nam potrzeba - zarówno od strony klasy Element, jak i od strony klasy Events i obiektu Event. W następnych częściach kursu niewątpliwie wykorzystamy tą wiedzę by manipulować strukturą drzewa dokumentu.

Komentarze do wpisu "MooTools 1.2 - zdarzenie DOMContentLoaded":

1. Wasacz napisał(a):
14 sierpnia 2008, 22:41:01

Odnośnie hacków w CSS:

* http://csshacks.devbox.pl/ * http://mgorny.jogger.pl/2008/07/15/hakiem-w-mozille/

PS: Włącz albo pełne Textile, albo wyłącz je wcale :-s

2. Dziudek napisał(a):
14 sierpnia 2008, 22:48:05

@Wasacz – mnie chodziło raczej o jakieś zupełne braki typu brak natywnej obsługi position:fixed w IE6 czy bug związany z generated content swego czasu opisany przez Riddle’a ;) A co do hacków w CSS – osobiście wolę jednak komentarze warunkowe – sprawdzają się idealnie dla IE6/7, a syfu w kodzie CSS nie ma ;) No a pozostałe przeglądarki raczej dają radę ;) Ale i tak dzięki za link – może kiedyś drastycznej sytuacji się przyda, choć póki co wychodziłem obronną ręką bez nich :)

3. Wasacz napisał(a):
14 sierpnia 2008, 22:49:36

Ja też wychodzę z założenia, że bez tego da się żyć. A dla przeglądarek innych niż IE to raczej się poprawia to, co jest zabugowane, a nie doklepuje to, czego nie ma ^^

4. Dziudek napisał(a):
14 sierpnia 2008, 22:51:44

@Wasacz – zależy – prosty przykład to text-shadow: Opera i Safari już wspierają, Firefox 3.1 też będzie wspierał, a reszta musi niestety mieć podaną jakąś protezę albo wcale efektu nie wyświetlać ;)

5. Wasacz napisał(a):
14 sierpnia 2008, 22:54:08

Cień tekstu to zły przykład, bo oprócz hacków dochodzi jeszcze dostępność i to ssące powielanie tekstu. A brak cienia jest tak samo mało istotny jak brak zaokrąglonego obramowania itd.

No ale mniejsza o to. Odnośnie wpisu – cieszy mnie, że Safari wreszcie ma DOMContentLoaded. Ciekawe tylko, czy będzie/jest w Konquerorze.

6. Dziudek napisał(a):
14 sierpnia 2008, 22:58:12

Konqueror raczej dopiero mieć będzie, bo widzę ostatnia edycja stable z 17 Października 2007 ;)

7. Rafael napisał(a):
14 sierpnia 2008, 22:58:23

Nie pamiętam, jak jest to zrobione w MooTools, ale w przypadku jQuery zastosowano inną sztuczkę, która nie wymaga korzystania z document.write w przypadku IE. Chyba się sprawdza, bo jeszcze jej nie porzucono. Link do informacji na temat tej „techniki”: http://javascript.nwbox.com/IEContentLoaded/
w kodzie jQuery 1.2.6 do znalezienia w okolicach linii 2345 :-)

8. Dziudek napisał(a):
14 sierpnia 2008, 23:00:22

@Rafael – to pewnie zastosowano w jednej z ostatnich edycji jQuery, bo pamiętam, że jeszcze względnie niedawno obie biblioteki bazowały na tym samym – ale co to za problem przerobić dla MooTools plik DomReady.js ;)

9. Dziudek napisał(a):
14 sierpnia 2008, 23:04:17

@Rafael – a przepraszam w Moo 1.2 już nie ma co poprawiać ^^ :

case 'trident': var temp = document.createElement('div'); (function(){ ($try(function(){ temp.doScroll('left'); return $(temp).inject(document.body).set('html', 'temp').dispose(); })) ? domready() : arguments.callee.delay(50); })();

Pamiętam, że jeszcze w wersji beta było document.write, albo już mi się te mootoolsy mieszają :D

10. Rafael napisał(a):
15 sierpnia 2008, 00:34:30

Jak dobrze kojarze, w nightly firefoksa z tego tygodnia dopatrzylem sie chyba dodania obslugi atrybutu defer dla <script>. Moze w Firefoksie 3.1 bedzie dostepne?!
Swoja droga, to troche smieszne, zeby na tym etapie rozwoju przegladarki nadal nie obslugiwaly w pelni HTMLa – starego standardu, ktory doczekal sie nawet swojego nastepcy (XHTML) :-P

11. felippe napisał(a):
27 sierpnia 2008, 17:12:07

Jeszcze w ramach komentarza, że warto ;)

Prosty przykład – mamy standardowy link (a href=...), który ma być obsługiwany przez mootools i ładnie wczytać np obrazek do diva (ach ten piękny SqeezeBox;) ). Jeśli będzie to w onLoad, to jak ktoś się pospieszy i cliknie w link zanim wszystko na stronie będzie załadowane, to nam właduje ów obrazek po prostu do okna (wykona linka). Zaś domready takie przypadki ograniczy (bo skoro jest strona widoczna – nawet jeszcze bez obrazków – to znaczy, że struktura DOM jest już wczytana)

Dodaj komentarz:

Textile Lite włączony ( szczegółowy opis znaczników ):
*strong* | # lista numerowana | * lista wypunktowana | _em_ | __italic__ | "link":http:// | bq. cytat.