Gebeurtenislisteners
Flash Player 9 of hoger, Adobe AIR 1.0 of hoger
Gebeurtenislisteners, die ook gebeurtenishandlers worden genoemd, zijn functies die door Flash Player en AIR worden uitgevoerd als reactie op specifieke gebeurtenissen. Het toevoegen van een gebeurtenislistener bestaat uit twee stappen. Eerst maakt u een functie of een klassenmethode die door Flash Player of AIR kan worden uitgevoerd als reactie op de gebeurtenis. Dit wordt soms de listenerfunctie of gebeurtenishandlerfunctie genoemd. Vervolgens gebruikt u de methode
addEventListener()
om de listenerfunctie te registreren bij het doel van de gebeurtenis of bij een willekeurig weergaveoverzichtobject dat in de juiste gebeurtenisstroom ligt.
Een listenerfunctie maken
Het maken van listenerfuncties is één gebied waarop het ActionScript 3.0-gebeurtenismodel afwijkt van het DOM-gebeurtenismodel. In het DOM-gebeurtenismodel is een duidelijk verschil tussen een gebeurtenislistener en een listenerfunctie: een gebeurtenislistener is een instantie van een klasse die de interface EventListener implementeert, terwijl een listenerfunctie een methode van die klasse met de naam
handleEvent()
is. In het DOM-gebeurtenismodel registreert u de klasseninstantie die de listenerfunctie bevat en niet de eigenlijke listenerfunctie.
In het ActionScript 3.0-gebeurtenismodel bestaat er geen onderscheid tussen een gebeurtenislistener en een listenerfunctie: ActionScript 3.0 kent geen interface EventListener en listenerfuncties kunnen buiten een klasse of als deel van een klasse worden gedefinieerd. Verder hoeven listenerfuncties niet
handleEvent()
te worden genoemd. Elke geldige naam is toegestaan. In ActionScript 3.0 registreert u de naam van de feitelijke listenerfunctie.
Listenerfunctie die buiten een klasse is gedefinieerd
Met de volgende code wordt een eenvoudig SWF-bestand gemaakt waarmee een rood vierkant wordt weergegeven. Een listenerfunctie met de naam
clickHandler()
, die geen deel uitmaakt van een klasse, luistert naar muisklikgebeurtenissen op het rode vierkant.
package
{
import flash.display.Sprite;
public class ClickExample extends Sprite
{
public function ClickExample()
{
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
class ChildSprite extends Sprite
{
public function ChildSprite()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, clickHandler);
}
}
function clickHandler(event:MouseEvent):void
{
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
Wanneer een gebruiker met het resulterende SWF-bestand communiceert door op het vierkant te klikken, genereert Flash Player of AIR de volgende trace-uitvoer:
clickHandler detected an event of type: click
the this keyword refers to: [object global]
Het gebeurtenisobject wordt als argument doorgegeven aan
clickHandler()
. Hierdoor kan het gebeurtenisobject door de listenerfunctie worden gecontroleerd. In dit voorbeeld gebruikt u de eigenschap
type
van het gebeurtenisobject om te controleren of de gebeurtenis een klikgebeurtenis is.
In het voorbeeld wordt ook de waarde van het trefwoord
this
gecontroleerd. In dit geval vertegenwoordigt
this
het algemene object. Dit is logisch, omdat de functie buiten enige aangepaste klasse of enig aangepast object is gedefinieerd.
Listenerfunctie die als klassenmethode is gedefinieerd
Het volgende voorbeeld is gelijk aan het vorige ClickExample-voorbeeld, met het verschil dat de functie
clickHandler()
als een methode van de klasse ChildSprite is gedefinieerd:
package
{
import flash.display.Sprite;
public class ClickExample extends Sprite
{
public function ClickExample()
{
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
class ChildSprite extends Sprite
{
public function ChildSprite()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, clickHandler);
}
private function clickHandler(event:MouseEvent):void
{
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
}
Wanneer een gebruiker met het resulterende SWF-bestand communiceert door op het rode vierkant te klikken, genereert Flash Player of AIR de volgende trace-uitvoer:
clickHandler detected an event of type: click
the this keyword refers to: [object ChildSprite]
Het trefwoord
this
verwijst naar de ChildSprite-instantie met de naam
child
. Dit gedrag wijkt af van het gedrag in ActionScript 2.0. Als u componenten gebruikte in ActionScript 2.0, weet u wellicht nog wel dat wanneer een klassenmethode werd doorgegeven aan
UIEventDispatcher.addEventListener()
, het bereik van de methode was gekoppeld aan de component waardoor de gebeurtenis werd verzonden en niet aan de klasse waarin de listenermethode werd gedefinieerd. Met andere woorden, als u deze techniek in ActionScript 2.0 gebruikte, verwees het trefwoord
this
naar de component die de gebeurtenis verzond en niet naar de ChildSprite-instantie.
Dit kon een serieus probleem voor sommige programmeurs zijn, omdat dit betekende dat deze geen toegang hadden tot andere methoden en eigenschappen van de klasse waarin de listenermethode werd gedefinieerd. Als oplossing konden ActionScript 2.0-programmeurs de klasse
mx.util.Delegate
gebruiken om het bereik van de listenermethode te wijzigen. Dit is echter niet meer nodig, omdat ActionScript 3.0 een gekoppelde methode maakt wanneer
addEventListener()
wordt aangeroepen. Als gevolg hiervan verwijst het trefwoord
this
naar de ChildSprite-instantie met de naam
child
en heeft de programmeur toegang tot de andere methoden en eigenschappen van de klasse ChildSprite.
Gebeurtenislistener waarvan het gebruik wordt afgeraden
Er bestaat een derde techniek waarbij u een algemeen object maakt met een eigenschap die verwijst naar een dynamisch toegewezen listenerfunctie. Het gebruik hiervan wordt echter niet aanbevolen. Deze techniek wordt hier besproken, omdat deze veel werd gebruikt in ActionScript 2.0, maar in ActionScript 3.0 beter niet gebruikt kan worden. Deze techniek wordt afgeraden omdat het trefwoord
this
naar het algemene object verwijst en niet naar het listenerobject.
Het volgende voorbeeld is gelijk aan het vorige ClickExample-voorbeeld, met het verschil dat de listenerfunctie is gedefinieerd als deel van een algemeen object met de naam
myListenerObj
:
package
{
import flash.display.Sprite;
public class ClickExample extends Sprite
{
public function ClickExample()
{
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
class ChildSprite extends Sprite
{
public function ChildSprite()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, myListenerObj.clickHandler);
}
}
var myListenerObj:Object = new Object();
myListenerObj.clickHandler = function (event:MouseEvent):void
{
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
De resultaten van de trace zien er als volgt uit:
clickHandler detected an event of type: click
the this keyword refers to: [object global]
Men zou verwachten dat
this
naar
myListenerObj
verwijst en dat de trace-uitvoer [
object Object
] is. Dit is echter niet het geval, this verwijst naar het algemene object. Wanneer u de naam van een dynamische eigenschap als argument doorgeeft aan
addEventListener()
, kan Flash Player of AIR geen gekoppelde methode maken. De reden hiervoor is dat u als parameter
listener
slechts het geheugenadres van de listenerfunctie doorgeeft en dat Flash Player en AIR dit geheugenadres op geen enkele manier kunnen koppelen aan de instantie
myListenerObj
.
Gebeurtenislisteners beheren
U kunt listenerfuncties beheren met behulp van de methoden van de interface IEventDispatcher. De interface IEventDispatcher is de ActionScript 3.0-versie van de interface EventTarget van het DOM-gebeurtenismodel. Hoewel de naam IEventDispatcher lijkt te impliceren dat het hoofddoel het verzenden van gebeurtenisobjecten is, worden de methoden van deze klasse veel vaker gebruikt voor het registreren van, controleren op en verwijderen van gebeurtenislisteners. De interface IEventDispatcher definieert vijf methoden, zoals in de volgende code wordt weergegeven:
package flash.events
{
public interface IEventDispatcher
{
function addEventListener(eventName:String,
listener:Object,
useCapture:Boolean=false,
priority:Integer=0,
useWeakReference:Boolean=false):Boolean;
function removeEventListener(eventName:String,
listener:Object,
useCapture:Boolean=false):Boolean;
function dispatchEvent(eventObject:Event):Boolean;
function hasEventListener(eventName:String):Boolean;
function willTrigger(eventName:String):Boolean;
}
}
De Flash Player-API implementeert de interface IEventDispatcher met de klasse EventDispatcher, die als basisklasse fungeert voor alle klassen die gebeurtenisdoelen of onderdelen van een gebeurtenisstroom kunnen zijn. De klasse DisplayObject overerft bijvoorbeeld van de klasse EventDispatcher. Dit betekent dat elk object op het weergaveoverzicht toegang heeft tot de methoden van de interface IEventDispatcher.
Gebeurtenislisteners toevoegen
De methode
addEventListener()
is het werkpaard van de interface IEventDispatcher. U gebruikt deze voor het registreren van de listenerfuncties. De twee vereiste parameters zijn
type
en
listener
. U gebruikt de parameter
type
om het type gebeurtenis op te geven. U gebruikt de parameter
listener
om op te geven welke listenerfunctie wordt uitgevoerd wanneer de gebeurtenis plaatsvindt. De parameter
listener
kan een verwijzing zijn naar een functie of naar een klassenmethode.
Gebruik geen haakjes bij het opgeven van de parameter
listener
. De functie
clickHandler()
wordt bijvoorbeeld zonder haakjes opgegeven in de volgende aanroep van de methode
addEventListener()
:
addEventListener(MouseEvent.CLICK, clickHandler)
Met de parameter
useCapture
van de methode
addEventListener()
kunt u controleren in welke fase van de gebeurtenisstroom de listener actief wordt. Als
useCapture
op
true
is ingesteld, wordt de listener actief tijdens de vastlegfase van de gebeurtenisstroom. Als
useCapture
op
false
is ingesteld, wordt de listener actief tijdens de doel- en terugkoppelfasen van de gebeurtenisstroom. Wanneer u in alle drie fasen naar de gebeurtenis wilt luisteren, roept u
addEventListener()
tweemaal aan, één keer met
useCapture
ingesteld op
true
en één keer met
useCapture
ingesteld op
false
.
De parameter
priority
van de methode
addEventListener()
maakt niet officieel deel uit van het DOM Level 3-gebeurtenismodel. Het is opgenomen in ActionScript 3.0 om u meer flexibiliteit te bieden bij het indelen van de gebeurtenislisteners. Wanneer u
addEventListener()
aanroept, kunt u de prioriteit voor die gebeurtenislistener instellen door een geheel-getalwaarde als parameter
priority
door te geven. De standaardwaarde is 0, maar u kunt deze wijzigen in een negatieve of positieve geheel-getalwaarde. Hoe hoger het getal, des te sneller die gebeurtenislistener wordt uitgevoerd. Gebeurtenislisteners met dezelfde prioriteit worden uitgevoerd in de volgorde waarin deze zijn toegevoegd. Hoe eerder een listener wordt toegevoegd, des te sneller deze wordt uitgevoerd.
Met de parameter
useWeakReference
kunt u opgeven of de verwijzing naar de listenerfunctie zwak of normaal is. Als u deze parameter op
true
instelt, kunt u situaties vermijden waarbij listenerfuncties in het geheugen aanwezig blijven, terwijl deze niet meer vereist zijn. Flash Player en AIR maken gebruik van een techniek voor het verwijderen van objecten uit het geheugen die niet meer in gebruik zijn. Deze techniek wordt
opschonen
genoemd. Een object is niet meer in gebruik als er geen verwijzingen naar bestaan. De opschoonfunctie negeert zwakke verwijzingen. Dit betekent dat als er alleen een zwakke verwijzing naar een listenerfunctie bestaat, de listenerfunctie in aanmerking komt voor opschonen.
Gebeurtenislisteners verwijderen
U kunt de methode
removeEventListener()
gebruiken om een gebeurtenislistener te verwijderen die u niet meer nodig hebt. Het is raadzaam om alle listeners die niet meer worden gebruikt, te verwijderen. Vereiste parameters zijn onder meer de parameters
eventName
en
listener
. Dit zijn dezelfde vereiste parameters als voor de methode
addEventListener()
. U kunt tijdens alle gebeurtenisfasen naar gebeurtenissen luisteren door
addEventListener()
tweemaal aan te roepen, één keer met
useCapture
ingesteld op
true
en één keer met deze parameter ingesteld op
false
. Als u beide gebeurtenislisteners wilt verwijderen, roept u
removeEventListener()
tweemaal aan, één keer met
useCapture
ingesteld op
true
en één keer met deze parameter ingesteld op
false
.
Gebeurtenissen verzenden
De methode
dispatchEvent()
kan door gevorderde programmeurs worden gebruikt om een aangepast gebeurtenisobject naar de gebeurtenisstroom te verzenden. De enige parameter die door deze methode wordt geaccepteerd, is een verwijzing naar een gebeurtenisobject, dat een instantie moet zijn van de klasse Event of van een subklasse van de klasse Event. Als de gebeurtenis is verzonden, wordt de eigenschap
target
van het gebeurtenisobject ingesteld op het object waarop
dispatchEvent()
was aangeroepen.
Controleren op bestaande gebeurtenislisteners
De laatste twee methoden van de interface IEventDispatcher bevatten nuttige informatie over het bestaan van gebeurtenislisteners. De methode
hasEventListener()
retourneert
true
als er een gebeurtenislistener is gevonden voor een specifiek gebeurtenistype op een bepaald weergaveoverzichtobject. De methode
willTrigger()
retourneert ook
true
als er een listener is gevonden voor een bepaald weergaveobject, maar
willTrigger()
zoekt niet alleen naar listeners op dat weergaveobject, maar ook naar listeners op alle voorouders van dat weergaveoverzichtobject voor alle fasen van de gebeurtenisstroom.
Foutgebeurtenissen zonder listeners
Uitzonderingen, en niet gebeurtenissen, vormen het belangrijkste mechanisme voor foutafhandeling in ActionScript 3.0. Foutafhandeling werkt echter niet voor asynchrone bewerkingen zoals het laden van bestanden. Als tijdens een dergelijke asynchrone bewerking een fout optreedt, verzenden Flash Player en AIR een foutgebeurtenisobject. Als u geen listener voor de foutgebeurtenis maakt, wordt door de foutopsporingsversies van Flash Player en AIR een dialoogvenster weergegeven met informatie over de fout. Zo genereert de foutopsporingsversie van Flash Player het volgende dialoogvenster waarin de fout wordt beschreven wanneer de toepassing een bestand vanaf een ongeldige URL probeert te laden:
De meeste foutgebeurtenissen zijn gebaseerd op de klasse ErrorEvent en hebben als zodanig een eigenschap met de naam
text
, waarmee het foutbericht wordt opgeslagen dat door Flash Player of AIR wordt weergegeven. De twee uitzonderingen zijn de klassen StatusEvent en NetStatusEvent. Deze klassen hebben een eigenschap
level
(
StatusEvent.level
en
NetStatusEvent.info.level
). Wanneer de waarde van de eigenschap
level
gelijk is aan "
error
", worden deze gebeurtenistypen als foutgebeurtenissen beschouwd.
Een foutgebeurtenis zorgt er niet voor dat de uitvoering van een SWF-bestand wordt afgesloten. Deze wordt alleen weergegeven als een dialoogvenster in de foutopsporingsversies van de insteekmodules van de browser en zelfstandige spelers, als een bericht in het uitvoervenster in de oorspronkelijke speler en als een item in het logbestand voor Adobe Flash Builder. In de releaseversies van Flash Player of AIR levert een foutgebeurtenis geen enkele melding op.
|
|
|
|
|