A Javascript programozási nyelv

Eseménykezelés

Eseménykezelők működése

A JavaScript programok nem feltétlenül sorról sorra hajtódnak végre. Eseményeket is észlelhetnek és válaszolhatnak ezekre. Az események a böngészőben következnek be, például ha egy felhasználó egy gombra kattint, mozgatja az egérmutatót, vagy a kiszolgálóról egy weboldalt, vagy képet tölt le.

A sokféle eseménykezelő segítségével könnyen válaszolhatunk az egérrel, illetve a billentyűzettel kiadott parancsokra vagy más bekövetkező eseményekre. Az események teszik a JavaScripttel bővített weboldalainkat interaktívvá.

Az események észlelésére és megválaszolására használatos kódok az eseménykezelők, amelyek a JavaScript talán leghasznosabb lehetőségei.

Objektumok és események

A JavaScript objektumokban tárolja a weboldalak különféle adatait: gombokat, hivatkozásokat, képeket, ablakokat... Egy esemény több helyen is bekövetkezhet, tehát minden esemény egy objektumhoz kapcsolódik.

Minden eseménynek van neve. Például az onMouseOver esemény akkor következik be, ha az egeret egy objektum fölé visszük az oldalon. Ha az egérmutató egy hivatkozás fölé áll, az onMouseOver a hivatkozás eseménykezelőjéhez továbbítódik (ha az rendelkezik ilyennel).

Eseménykezelők létrehozása

Eseménykezelő létrehozásához nem kell < script > elempárt használnunk, csupán egy html elemet kell egy eseménykezelő jellemzőivel bővítenünk. Példaként nézzünk egy onMouseOver eseménykezelővel ellátott hivatkozást:

< a href="http://www.elte.hu" onMouseOver="window.alert('itt az egér')"> katt ide </a>

Élesben:

Az egyszeres és kétszeres idézőjelek szerepe felcserélhető, de mindkét helyen nem használhatjuk ugyanazt, csak ha escape-eljük: \"

Ha több utasítást szeretnénk futtatni, akkor ésszerűbb megoldás, ha egy függvényt hozunk létre a dokumentum fejlécében és azt hívjuk meg.

Eseménykezelők módosítása JavaScript programból

Ahelyett, hogy az eseménykezelőt a HTML dokumentumban határoznánk meg, azt is megtehetjük, hogy a JavaScripttel egy függvénynek adjuk az eseménykezelő szerepét. Így az eseménykezelőket bizonyos feltételek alapján ki- és bekapcsolhatjuk, vagy az eseményt kezelő függvényt dinamikusan megváltoztathatjuk. Ezzel a módszerrel külső JavaScript fájlban határozhatjuk meg az eseménykezelőt és ezzel elválaszthatjuk a html és a JavaScript kódot egymástól.

Az eseménykezelő ilyen meghatározásához először meg kell határoznunk egy függvényt, majd azt eseménykezelőként kell alkalmaznunk. Az eseménykezelők a document vagy más, események fogadására képes objektum tulajdonságaként tárolódnak. Például az alábbi utasítások a mousealert függvényt határozzák meg, majd a document onMouseDown eseménykezelőjeként alkalmazzák:

function mousealert() { alert("kattintottál az egérrel"); } document.onmousedown = mousealert;

Ezzel a módszerrel bármelyik HTML objektumhoz beállíthatunk eseménykezelőt, de még egy lépésre szükség lesz: először meg kell találnunk az elemnek megfelelő objektumot. Ehhez a document.getElementById() függvényt használjuk. Először határozzunk meg egy elemet a HTML oldal forrásában, és adjunk meg hozzá egy id jellemzőt:

< a href="..." id="link1">

Ezután a JavaScript kóddal keressük meg az objektumot, és alkalmazzuk rá az eseménykezelőt:

obj = document.getElementById("link1"); obj.onclick = myFunction;

Ezt bármilyen objektummal megtehetjük amelyet egyedi id jellemzővel határoztunk meg a HTML fájlban. Ez a módszer alkalmas arra, hogy HTML kód kuszává tétele nélkül alkalmazzuk ugyanazt a függvényt több objektum eseményeinek kezelésére.

Több eseménykezelő

Mi a helyzet, ha azt szeretnénk, hogy egyszerre több dolog is történjen, amikor egy objektumra rákattintunk? Tegyük fel például, hogy egy gombra kattintva két függvényt (update és display) szeretnénk lefuttatni. Az onclick tulajdonsághoz nem rendelhetünk két függvényt.

Egyik megoldás egy olyan függvény meghatározása ami mindkét említett függvényt meghívja:

function UpdateDisplay() { update(); display(); }

Ez azonban nem ideális megoldás. Ha például két külső programot használunk és mindkettő szeretne egy onLoad eseményt adni az oldalhoz, kell lennie valamilyen megoldásnak, hogy kettőt adhassunk hozzá. A W3C DOM szabványban szerencsére szerepel egy függvény erre a célra: az addEventListener. Ez a függvény egy figyelőt határoz meg egy adott eseményhez és objektumhoz, és annyi figyelőfüggvényt adhatunk meg, amennyit csak akarunk.

Sajnos az addEventListener függvényt az Internet Explorer nem támogatja (legalábbis a 6-os és 7-es változatig), ezért e böngészőhöz egy másik függvényt (attachEvent) kell használnunk.

Az event objektum használata

Egy esemény bekövetkezésekor szükségünk lehet az esemény további adataira is: például egy billentyűeseménynél tudnunk kell, melyik billentyűt nyomták le. A DOM-ban ezeket az adatokat az event objektumban találhatjuk meg.

Az event használatához át kell azt adnunk az eseménykezelő függvényünknek. Például az alábbi sor egy onKeyPress eseményt határoz meg, amely az event objektumot egy függvénynek adja át:

< body onKeyPress="getkey(event)">

Ezután a függvényt úgy határozzuk meg, hogy az eseményt paraméterként vegye át:

function getkey(e) { ... }

A Mozilla alapú böngészők (Firefox és Netscape) az event objektumot automatikusan átadják az eseménykezelő függvénynek, így a fenti kód akkor is működik, ha az eseménykezelőt nem a HTML-ben, hanem a JavaScript kódban határoztuk meg. Az Internet Explorerben a legutóbbi eseményt a window.event objektum tárolja, így ott ez az objektum adódik át az eseménykezelőnek, ezért ha az eseménykezelőt JavaScripttel adtuk meg, nem fog működni, hacsak némi kóddal meg nem keressük előbb a megfelelő objektumot:

function getkey(e) { if (!e) e = window.event; }

Ez a kód megvizsgálja hogy az e változót meghatároztuk-e már. Ha nem, fogja a window.event objektumot, és az e változóba helyezi, így bármelyik böngészőt használjuk is, működőképes lesz az eseményobjektumunk.

Bár mind a Mozilla alapú böngészők, mind az Internet Explorer támogatják az event objektumot, sajnos más-más tulajdonságokkal. Az egyik olyan tulajdonság, amelyet mindkét böngésző támogat, az event.type, ami az esemény típusa. A típus nem más, mint az esemény neve, például egy onMouseOver eseménynél mouseover, egy onKeyPress eseménynél pedig keypress.

Az event objektum Internet Explorer (>4.0) által támogatott (gyakrabban használt) tulajdonságai:

Az event objektum Netscape (>4.0) és Firefox által támogatott (gyakrabban használt) tulajdonságai:

Az event.pageX és event.pageY tulajdonságok annak az elemnek a bal felső képpontját veszik alapul, ahol az esemény bekövetkezett, ami nem mindig esik egybe az egérmutató pontos helyzetével.

Az egér eseményei

A JavaScript az egéresemények észlelésére több eseménykezelőt is biztosít számunkra. Programunk észlelheti az egérmutató mozgását, az egérgomb lenyomását, felengedését, vagy mindkettőt.

onMouseOver és onMouseOut

Az onMouseOver akkor hívódik meg, amikor az egérmutatót valami objektum fölé visszük.

Az onMouseOut ezzel ellentétesen akkor fut le, amikor az egérmutató elhagyja az objektum körvonalait. Hacsak nem történik valami, akkor ez az onMouseOver esemény meghívása után mindig bekövetkezik.

Az onMouseOver és az onMouseOut eseménykezelők leggyakoribb felhasználási területe az olyan váltóképek (rollover) készítése, amelyek megváltoznak, ha az egérmutatót föléjük visszük.

Az onMouseMove esemény

Az onMouseMove esemény az egérmutató mozgásakor következik be. Természetesen ez elég gyakran megtörténik: az esemény több százszor is kiváltódhat, amint az egeret a képernyőn mozgatjuk.

Az események nagy száma miatt, a böngészők alapértelmezés szerint nem támogatják az onMouseMove eseményt. Ahhoz, hogy egy oldalon használhassuk, eseményelfogásra van szükség. Ez hasonlít a már megismert dinamikus eseményekhez, de egyes régebbi böngészők esetén további lépésre is szükség van.

Mindkét böngészőben egy függvényt kell beállítanunk a dokumentum vagy más objektum onMouseMove eseménykezelőjeként. Például az alábbi sor a dokumentum onMouseMove kezelőjét egy MoveHere nevű függvényre állítja, amit ugyanazon az oldalon kell meghatároznunk:

document.onMouseMove = MoveHere;

A Netscape régebbi változataiban emellett a document.captureEvents tagfüggvénnyel is kell az eseményt engedélyezni:

document.captureEvents(Event.MOUSEMOVE);

Az egérgombok figyelése

Az egérgombokat is figyelhetjük az eseményekkel. Az onClick esemény akkor következik be, ha az egér a megfelelő objektumon áll, és a felhasználó kattint, azaz lenyomja az egérgombot, majd (az egérmutatót továbbra is az objektum fölött tartva) felengedi azt.

Például az alábbi eseménykezelő akkor fut le, ha egy hivatkozásra kattintunk, és ekkor egy figyelmeztető üzenet jelenik meg:

< a href="http://www.elte.hu" onClick="alert('Most elhagyod ezt az oldalt')"> Kattints ide </a>

Élesben:

Ebben az esetben az onClick eseménykezelő még azelőtt fut le, hogy a hivatkozott oldal betöltődne a böngésző ablakába. Így egyszerűen megoldható az, hogy a hivatkozásra kattintva előbb a felhasználó választhasson, hogy valóban elhagyja-e az oldalt.

Ha az onClick eseménykezelő false értékkel tér vissza, a hivatkozott oldal nem töltődik be. Az alábbi kód egy hivatkozást mutat be, amely kattintáskor megerősítést kér a felhasználótól. Ha a felhasználó a Mégse (Cancel) gombra kattint, semmi nem történik, ha az OK gombra, akkor betöltődik a hivatkozott oldal

< a href="http://www.elte.hu" onClick="return(window.confirm('Biztos vagy benne?'));"> Klikk ide </a>

Élesben:

Ebben a példában a return utasítás tartalmazza az eseménykezelőt. Ez biztosítja, hogy a Mégse gombra kattintás eredményeképpen létrejövő false érték visszatér az eseménykezelőhöz, így a hivatkozás nem töltődik be.

Az onDblClick hasonlóan működik, de ez a dupla kattintásokra figyel. Mivel a hivatkozások általában egyetlen kattintást igényelnek, megoldhatjuk hogy más történjen, ha egy hivatkozásra egyszer, illetve duplán kattintunk. A képekre vagy más objektumokra való dupla kattintást is érzékelhetjük.

Az egérgombok eseményének figyelésére további két esemény is a rendelkezésünkre áll:

Ez a két esemény tehát az egérkattintás egyik és másik felét jelenti. Ha az egész kattintást (a gomb lenyomását és felengedését) szeretnénk észlelni, használjuk az onClick eseménykezelőt.

Az event objektum, button tulajdonságának segítségével állapíthatjuk meg, melyik egérgombbal kattintott a felhasználó. A bal gomb értéke 0 vagy 1, a jobbé 2. Ez a tulajdonság az onClick, onDblClick, onMouseUp és onMouseDown eseményeknél használható.

A böngészők általában nem észlelik az onClick és onDblClick eseményeket, ha az egér jobb gombjával hajtjuk végre őket. Ha a jobb gombra is figyelni szeretnénk, az onMouseDown használata a legmegbízhatóbb módszer.

A billentyűzet eseményei

A JavaScript képes a billentyűesemények észlelésére is. E célra leggyakrabban az onKeyPress eseménykezelőt használjuk, amely akkor fut le, ha egy billentyűt lenyomnak majd felengednek, illetve ha a billentyűt lenyomva tartják. Az egérgombokhoz hasonlóan itt is lehetőség van csak a lenyomás vagy csak a felengedés észlelésére, ezekre az onKeyDown és az onKeyUp eseménykezelőket használjuk.

Természetesen azt is tudnunk kell, hogy az illető melyik billentyűt nyomta le. Ezt az event objektummal határozhatjuk meg, amely az esemény bekövetkezésekor az eseménykezelőhöz továbbítódik. A Netscape-ben és a Firefoxban az event.wich tulajdonság tárolja a lenyomott billentyű ASCII kódját, az Internet Explorerben az event.keyCode szolgálja ugyanezt a célt.

A beírt karakterek megjelenítése

Ha a billentyűkódok helyett inkább a valódi karakterekkel dolgoznánk, a kódok átalakítására a fromCharCode karakterfüggvényt használhatjuk. Ez egy ASCII kódból a megfelelő karaktert állítja elő. Például az alábbi utasítás az event.wich értékét alakítja át karakterré és helyezi el a key változóban:

key = String.fromCharCode(event.wich);

Mivel a különböző böngészők más-más módon adják vissza a billentyűkódot, a karakterek böngészőfüggetlen megjelenítése gondokat okozhat, de készíthetünk olyan programot, ami bármelyik böngészőben képes a karakterek megjelenítésére. Az alábbi függvény minden karaktert kiír, ahogy beírjuk őket:

function DisplayKey(e) { // Melyik billentyűt nyomták le if (e.keyCode) keycode = e.keyCode; else keycode = e.wich; character = String.fromCharCode(keycode); // Célbekezdés objektumának megkeresése k = document.getElementById("keys"); // A karakter hozzáadása a bekezdéshez k.innerHTML += character; }

a DisplayKey() függvény megkapja az event objektumot az eseménykezelőtől, és az e változóban tárolja azt. Ellenőrzi, hogy az e.keyCode tulajdonság létezik-e, és ha igen, annak értékét a keycode változóba helyezi. Egyébként feltételezi, hogy a felhasználó Netscape vagy Firefox böngészőt futtat, és a keycode változót az e.wich tulajdonsághoz rendeli.

A függvény többi része karakterré alakítja a billentyűkódot és hozzáadja a dokumentum keys azonosítójú bekezdéséhez.

Az onLoad és onUnload események használata

Egy másik gyakran használt esemény az onLoad, amely akkor következik be, amikor az aktuális oldal (minden képpel és egyéb objektummal együtt) letöltődött a kiszolgálóról.

Az onLoad esemény a window objektumhoz kapcsolódik, meghatározásához pedig egy eseménykezelőt kell alkalmaznunk a < body > elemben. Az alábbi @lt body > elem egy egyszerű eseménykezelő segítségével figyelmeztető üzenetet küld a felhasználónak, ha az oldal betöltődött:

< body onLoad="alert('Az oldal betöltődött');">

Az onLoad esemény a HTML oldal betöltődése és megjelenítése után következik be. Ebből következik, hogy az onLoad eseménykezelőben nem használhatjuk a document.write és document.open utasításokat, hiszen azok felülírnák a jelenlegi dokumentumot.

A Javascript 1.1 és későbbi változataiban a képek is rendelkezhetnek onLoad eseménykezelővel. Ha egy < img > elemhez onLoad eseménykezelőt állítunk be, akkor az adott kép teljes betöltődése után következik be az esemény.

Az onLoad esemény a JavaScript kódban úgy állítjuk be, hogy egy függvényt rendelünk a window objektum onload tulajdonságához:

window.onload = MyFunction;

A < body > elemhez egy onUnload eseményt is meghatározhatunk. Ez az esemény akkor következik be, amikor a látogató új oldalt tölt be az ablakba, vagy bezárja a böngészőablakot.