Udalostné skriptovanie stránok

Skriptovanie založené na udalostiach (event driven scripting) je v súčastnosti obtiažne použiť na webových stránkach, pretože prehliadače používajú veľmi rozdielne spracovanie udalostí. Ich implementácia sa veľmi vzďaľuje od DOM Events (či už úrovne 2, alebo úrovne 3).

Jednoduché použitie eventov umožňuje JS knižnica lib.js. Zjednocuje rozdielne chovania prehliadačov a zaobaľuje ich do dvoch hlavných funkcií:

  • addEvent() – pridá udalosť k daným prvkom,
  • remEvent() – odstráni udalosť z daných prvkov,

Pomocná funkcia addLoadEvent()rieši problém s naviazaním udalosti load v Opere. (Pridá dokumentu udalosť podobne ako HTML zápis <body onload="...">.)

Knižnica lib.js tiež zjednodušuje prácu s prvkami v dokumente. Dôležité funkcie:

  • getElem(id) – získa referenciu na element podľa daného ID. Ak id už je referenciou na prvok, vráti tento prvok (element).
  • getAll(name, parent) – vráti všetky elementy, ktorých názov je name a nachádzajú sa v elemente getElem(parent) (funkcia si sama zistí, či je parent element alebo ID elementu. Ak je nedefinovaný, použije objekt document).
  • getElementsByClass() – získa všetky elementy s určitou triedou. Má viacero parametrov vymedzujúcich oblasť prehľadávaných elementov.
  • hasClass(elm, className) – zistí, či element má definovanú určitú triedu.
  • addClass(elm, className, duplicates) – elementu priradí triedu className. duplicates určuje, či trieda môže byť pridaná viacnásobne.
  • remClass(elm, className, all) – odstráni triedu z elementu. all určuje, či odstráni všetky výskyty triedy.

Spracovanie (X)HTML dokumentu

Pre správne (a funkčné) použitie funkcie getElem() je potrebné pochopiť, ako je spracovávaný (X)HTML dokument:

  • HTML parser načítava dokument postupne a prvky sú dostupné pre DOM postupne. Na prvok s atribútom id="" (ID) je teda možné sa odkazovať až potom, ako ho parser spracuje.
  • XHTML dokumenty podliehajú XML pravidlám a spracuváva ich XML parser až potom, ako je celý dokument načítaný. Všetky dáta sú dostupné pre DOM až po načítaní celého dokumentu.

Poznámka: XHTML dokument podlieha XML pravidlám pri XML mime type (napr. application/xhtml+xml­).
MSIE vždy používa HTML parser.

V oboch prípadoch je kompletná štruktúra dokumentu dostupná pre DOM až po načítaní celého dokumentu, kedy je vyvolaná udalosť load objektu window (alebo document v Opere). Funkcia k tejto udalosti sa naväzuje pomocou addLoadEvent().

<head>
  <script type="text/javascript">

// funkcia getElem() sa nevykoná a beh skriptu sa skončí,
// pretože prvok s id="p1" ešte neexistuje
var p1 = getElem("p1");

// po načítaní dokumentu sa vykoná funkcia Init()
addLoadEvent(Init);

function Init () {
  // po načítaní dokumentu sú už prvky podľa ID dostupné
  var p2 = getElem("p2");
  alert(p2);
}
  </script>
</head>
<body>
<p id="p1">Odstavec 1</p>
<p id="p2">Odstavec 2</p>
</body>

Jednoduché pridanie udalosti k elementu

Dnešný článok ukončím praktickou ukážkou pridania funkcie pre udalosť na nejaký element.

Problém: Zobrazenie textu odkazu a URI na ktoré odkazuje.

Riešenie: Pomocou udalostí naviažeme na každý odkaz obslužnú funkciu evt_Kliknutie ktorá vykoná daný príkaz.

<head>
  <script type="text/javascript">
// po načítaní dokumentu zavolá funkciu Init();
addLoadEvent(Init);

function Init() {
  // získanie všetkých odkazov v prvku #p1
  var a = getAll("a", "p1");

  // elms môže byť jeden element alebo kolekcia elemetov (pole)
  // pri kolekcii elementov je udalosť naviazaná na každý objekt v kolekcii
  addEvent(a, "click", evt_Kliknutie);
}

// handler - obslužná funkcia udalosti
function evt_Kliknutie(e) {
  // objekt e obsahuje informácie o zdroji udalosti
  // vlastnosť e.currentTarget obsahuje odkaz na zdroj udalosti
  // v tomto prípade to je odkaz, na ktorý bolo kliknuté
  var a = e.currentTarget;
  // zobrazí text odkazu a cieľ
  alert(a.innerHTML +": "+ a.href);

  // zabránenie "spracovaniu" hypertextového odkazu
  e.preventDefault();
}
  </script>
</head>
<body>
<p id="p1">
  <a href="page1.html">Stránka 1</a>,
  <a href="page2.html">stránka 2</a>,
  <a href="page3.html">stránka 3</a>.
</p>
</body>

Ukážka základného priradenia udalosti pomocou funkcie addEvent.

Základné používanie udalostí s knižnicou lib.js je veľmi jednoduché. Môžeme využiť aj posielanie argumentov obslužným funkciám (handlerom), ale to si ukážeme v ďalšom článku.

Odstránenie udalosti

// priradí udalosť k elementu
addEvent("p1", "mouseover", evt_HoverEfect);

// odstráni udalosť pre element
remEvent("p1", "mouseover", evt_HoverEfect);

Odstraňovanie eventov mi nefungovalo, v podstate argumenty by mali byť rovnaké ako pri pridaní eventu. Neviem ešte, či je chyba v prehliadačoch alebo v knižnici.


Udalostné skriptovanie mne osobne umožnilo veľmi rýchlo vyvinúť komplexné, inteligentné administračné rozhranie pre jeden CMS systém. Pri dobrom návrhu programovej logiky udalostné skriptovanie šetrí mnoho času a umožňuje vytvárať univerzálne funkcie pre obsluhu formulárov (validácia, filtrovanie <select> zoznamov a iné).

Poznámka: pre jednoduchosť som používal výrazy priradenie udalosti alebo naviazanie udalost. Pre pochopenie problematiky sú tieto výrazy (podľa mňa) dostačujúce. Správne sa však vždy jedná o „naviazanie obsluhovača udalosti na udalosť“ (naviazanie handleru na event).

Obsluhovač udalosti je funkcia, ktorá sa zavolá pri nastaní udalosti. Jednu udalosť môže obsluhovať aj viacej obsluhovačov (handlerov).

Aktualizácia: Príklad nefungoval, pretože som mal na serveri starú verziu lib.js a aj preklep v HTML kóde. Opravené 10. 8. 2005 o 13:06.