Xüx kalandjai az első osztályon :)

!Amíg nem olvastuk el a képek alatti szöveget, ne húzzuk rá az egeret a képekre!


Felhasználói szempontból továbbra sem látható semmi változás az ufo0.html-hez képest, viszont az oldalhoz tartozó Javascript állományra (ufo2.js) pillantva szembeötlő a kód tömörülésének a mértéke. A kezdo függvény egy sorra zsugorodott, s eseménykezelő függvényből is csak egy darabot tartalmaz a fájl. Ahhoz, hogy megértsük, miként is működik a szóban forgó kód, kicsit "gyorstalpalnunk" kell a Javascript eseménykezelő lehetőségeit illetően. Naszóval:

Kezdjük az utóbbival!
A megoldás kulcsa az, hogy egy esemény nem csupán azon az elemen hívódik meg, ahol az "megesik" (történetünkben egy adott IMG tag-nél), hanem az összes elemen is, mely tartalmazza a kérdéses elemet (minden szülőelemen, ahogy haladunk kifelé/fölfelé a fa-struktúrában). Esetünkben az esemény "felszivárgásának" útja: img >> div >> body >> html.
Nem véletlenül hívják ezt a folyamatot az esemény buborékolásának. Innentől már kézenfekvő, hogy ne az egyes IMG-ket figyeljük, történik-e valami esemény rajtuk, hanem az összes IMG tag egyetlen szülőelemét (esetünkben a div-ünket), hiszen a felbuborékoló esemény ott is fülöncsíphető, s miután elkaptuk, már csak azt kell megtudnunk, hogy a sok IMG tag közül melyiknél történt az adott esemény! Kérdés persze, hogyan tudhatjuk ezt meg? Itt kell visszatérnünk a fenti lista első pontjához, ugyanis, ha a szülőelemen kezeljük az eseményt (példánkban a kepek id-jű div-ünkön ), akkor az adott eseményobjektum target-jével tudjuk lekérdezni az eseményt eredetileg kiváltó elemet (azt, hogy melyik IMG-nél történt az esemény), így ahhoz nem kell külön id-t biggyesztenünk, csak a szülőelemhez. Ezt a lekérdezést láthatjuk a Javascript kód eseménykezelő függvényében lévő szelekció magjának első sorában:
var kepobjektum=esemenyobjektum.target;

Egy szemfüles hallgatónak persze nyilván szemet szúrhat maga a szelekció is, hiszen a konkrét példából nem következik triviálisan, hogy szükség van rá. Valóban, itt, most működik a dolog szelekció nélkül is. Viszont, ha más elemek is lennének a szülőelemen belül, ahol történhetne ez-az, nem csupán IMG tag-ek, akkor már le kellene ellenőriznünk, az eseményt eredetileg meghívó elem nevét is! Ezt szolgálja a szelekció fejében látható esemenyobjektum.target.tagName==="IMG" feltétel, ahol a tagName tulajdonság nagybetűsen adja vissza a HTML elem nevét, ahol az esemény eredetileg meghívásra került. (A 3 darab = jel, mint operátor kiküszöböli a Javascript gyengén típusos voltából fakadó, "szimpla" == összehasonlító operátor alkalmazásakor végzett automatikus konverziót, vagyis nem csupán érték, de típus szerinti egyezőséget is vizsgál.)

Tanulság: ha sok, hasonló vagy inkább azonos típusú eseményt kell kezelnünk, érdemes lehet az adott elemek szülőelemén elvégezni az eseménykezelést, így csupán egyetlen eseménykezelő függvényt kell megírnunk, s id-ból is csak egyre lesz szükségünk (a szülőelemére), amire regisztrálhatjuk az egyetlen eseménykezelő függvényünket. Mindehhez elég csupán azt tudnunk, hogy az események "felbubiznak" a szülőelemeken, ahol aztán elcsíphetjük őket, illetve azt, hogy az eseménykezelő függvény első paraméterén keresztül elérhető eseményobjektum segítségével megtudhatjuk, hogy eredetileg melyik elemnél került sor az esemény meghívására.