Ereignis-Listener, die auch als Ereignisprozeduren bezeichnet werden, sind Funktionen, die in Flash Player und AIR als Reaktion auf bestimmte Ereignisse ausgeführt werden. Ereignis-Listener werden in zwei Schritten hinzugefügt. Zunächst erstellen Sie eine Funktion oder Klassenmethode, die in Flash Player bzw. AIR als Reaktion auf das Ereignis ausgeführt wird. Diese wird gelegentlich als Listener-Funktion oder Ereignisprozedurfunktion bezeichnet. Im zweiten Schritt rufen Sie die
addEventListener()
-Methode auf, um die Listener-Funktion beim jeweiligen Ereignisziel oder einem Anzeigelistenobjekt zu registrieren, das sich im entsprechenden Ereignisablauf befindet.
Erstellen einer Listener-Funktion
Die Erstellung von Listener-Funktionen ist ein Bereich, in dem das ActionScript 3.0-Ereignismodell vom DOM-Ereignismodell abweicht. Im DOM-Ereignismodell gibt es eine klare Unterscheidung zwischen einem Ereignis-Listener und einer Listener-Funktion: Ein Ereignis-Listener ist eine Instanz einer Klasse, die die EventListener-Schnittstelle implementiert, wohingegeben eine Listener-Funktion eine Methode dieser Klasse mit dem Namen
handleEvent()
ist. Im DOM-Ereignismodell registrieren Sie anstelle der eigentlichen Listener-Funktion die Klasseninstanz, die die Listener-Funktion enthält.
Im ActionScript 3.0-Ereignismodell wird nicht zwischen Ereignis-Listenern und Listener-Funktionen unterschieden. ActionScript 3.0 verfügt über keine EventListener-Schnittstelle. Listener-Funktionen können außerhalb einer Klasse oder als Teil einer Klasse definiert werden. Darüber hinaus müssen Listener-Funktionen nicht stets den Namen
handleEvent()
tragen. Sie können mit einem beliebigen gültigen Bezeichner benannt werden. In ActionScript 3.0 registrieren Sie den Namen der eigentlichen Listener-Funktion.
Außerhalb einer Klasse definierte Listener-Funktionen
Im folgenden Programmcode wird eine einfache SWF-Datei erstellt, mit der ein rotes Quadrat angezeigt wird. Eine Listener-Funktion mit dem Namen
clickHandler()
, die nicht Bestandteil einer Klasse ist, wartet auf Mausklickereignisse für das rote Quadrat.
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);
}
Wenn ein Benutzer durch Klicken auf das Quadrat mit der entstandenen SWF-Datei interagiert, wird in Flash Player bzw. AIR die folgende Trace-Ausgabe erzeugt:
clickHandler detected an event of type: click
the this keyword refers to: [object global]
Beachten Sie, dass das Ereignisobjekt als Argument an
clickHandler()
übergeben wird. Dadurch kann mit der Listener-Funktion das Ereignisobjekt überprüft werden. In diesem Beispiel wird mit der
type
-Eigenschaft des Ereignisobjekts sichergestellt, dass es sich um ein Mausklickereignis handelt.
Im Beispiel wird auch der Wert des Schlüsselworts
this
überprüft. In diesem Fall repräsentiert
this
das globale Objekt. Dies ist schlüssig, da die Funktion außerhalb benutzerdefinierter Klassen und Objekte definiert wurde.
Als Methode einer Klasse definierte Listener-Funktionen
Das folgende Beispiel ist mit dem vorangegangenen identisch, in dem ebenfalls die ClickExample-Klasse definiert wurde. Die
clickHandler()
-Funktion ist diesmal jedoch als Methode der ChildSprite-Klasse definiert:
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);
}
}
Wenn ein Benutzer durch Klicken auf das rote Quadrat mit der entstandenen SWF-Datei interagiert, wird in Flash Player bzw. AIR die folgende Trace-Ausgabe erzeugt:
clickHandler detected an event of type: click
the this keyword refers to: [object ChildSprite]
Beachten Sie, dass sich das Schlüsselwort
this
auf die ChildSprite-Instanz mit dem Namen
child
bezieht. Dieses Verhalten ist anders als in ActionScript 2.0. Wenn Sie in ActionScript 2.0 Komponenten verwendet haben, erinnern Sie sich möglicherweise noch daran, dass beim Übergeben einer Klassenmethode an
UIEventDispatcher.addEventListener()
der Gültigkeitsbereich dieser Methode an die Komponente gebunden war, mit der das Ereignis gesendet wurde, und nicht an die Klasse, in der die Listener-Methode definiert wurde. Anders ausgedrückt, bezieht sich bei Verwendung dieser Technik in ActionScript 2.0 das Schlüsselwort
this
nicht auf die ChildSprite-Instanz, sondern auf die Komponente, mit der das Ereignis gesendet wird.
Dies stellte für einige Programmierer ein großes Problem dar, da sie deshalb nicht auf die anderen Methoden und Eigenschaften der Klasse zugreifen konnten, in der die Listener-Methode definiert war. Zum Umgehen des Problems konnten ActionScript 2.0-Programmierer die
mx.util.Delegate
-Klasse verwenden, um den Gültigkeitsbereich der Listener-Methode zu ändern. Dies ist nun jedoch nicht mehr erforderlich, da in ActionScript 3.0 beim Aufrufen von
addEventListener()
eine gebundene Methode erstellt wird. Dies führt dazu, dass sich das Schlüsselwort
this
auf die ChildSprite-Instanz mit dem Namen
child
bezieht und Programmierer Zugriff auf die anderen Methoden und Ereignisse der ChildSprite-Klasse haben.
Zu vermeidende Ereignis-Listener
Es liegt ein drittes Verfahren vor, bei dem Sie ein generisches Objekt mit einer Eigenschaft erstellen, die auf eine dynamisch zugewiesene Listener-Funktion verweist. Dieses Verfahren wird jedoch nicht empfohlen. Es wird hier erläutert, da es in ActionScript 2.0 ein gängiges Verfahren darstellte, es sollte jedoch in ActionScript 3.0 nicht verwendet werden. Dieses Verfahren wird nicht empfohlen, weil das Schlüsselwort
this
auf das globale Objekt und nicht auf das Listener-Objekt verweist.
Das folgende Beispiel ist mit dem vorangegangenen für die ClickExample-Klasse identisch. Die Listener-Funktion ist jedoch als Bestandteil eines generischen Objekts mit dem Namen
myListenerObj
definiert:
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);
}
Das Ergebnis der Trace-Ausgabe ist wie folgt:
clickHandler detected an event of type: click
the this keyword refers to: [object global]
Es wäre zu erwarten, dass sich
this
auf
myListenerObj
bezieht und
[object Object]
ausgegeben wird. Stattdessen wird auf das globale Objekt verwiesen. Wenn Sie den Namen einer dynamischen Eigenschaft als Argument an
addEventListener()
übergeben, kann in Flash Player oder AIR keine gebundene Methode erstellt werden. Der Grund hierfür ist, dass Sie beim Übergeben des Parameters
listener
lediglich die Speicheradresse der Listener-Funktion übergeben. In Flash Player und AIR kann diese Speicheradresse nicht mit der
myListenerObj
-Instanz verbunden werden
.
Verwalten von Ereignis-Listenern
Sie können Listener-Funktionen mithilfe der Methoden der IEventDispatcher-Schnittstelle verwalten. Die IEventDispatcher-Schnittstelle ist die ActionScript 3.0-Variante der EventTarget-Schnittstelle des DOM-Ereignismodells. Obwohl der Name „IEventDispatcher“ darauf hinzuweisen scheint, dass der Hauptzweck dieser Schnittstelle das Senden von Ereignisobjekten ist, werden die Methoden dieser Klasse in Wahrheit wesentlich häufiger zum Registrieren, Überprüfen und Entfernen von Ereignis-Listenern eingesetzt. Die IEventDispatcher-Schnittstelle definiert fünf Methoden, die im folgenden Codebeispiel dargestellt sind:
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;
}
}
Die Flash Player-API implementiert die IEventDispatcher-Schnittstelle mithilfe der EventDispatcher-Klasse. Diese dient als Basisklasse für alle Klassen, die ein Ereignisziel oder Teil des Ereignisablaufs sein können. Beispielsweise erbt die DisplayObject-Klasse von der EventDispatcher-Klasse. Das bedeutet, dass alle Objekte in der Anzeigeliste Zugriff auf die Methoden der IEventDispatcher-Schnittstelle haben.
Hinzufügen von Ereignis-Listenern
Die
addEventListener()
-Methode ist die wichtigste Methode der IEventDispatcher-Schnittstelle. Sie setzen sie ein, um Listener-Funktionen zu registrieren. Die beiden erforderlichen Parameter sind
type
und
listener
. Verwenden Sie den Parameter
type
, um den Ereignistyp anzugeben. Mit dem Parameter
listener
geben Sie die Listener-Funktion an, die beim Auftreten eines Ereignisses ausgeführt wird. Der Parameter
listener
kann ein Verweis auf eine Funktion oder eine Klassenmethode sein.
Verwenden Sie keine Klammer, wenn Sie den
listener
-Parameter spezifizieren. Beim folgenden Aufruf der
addEventListener()
-Methode wird die
clickHandler()
-Funktion beispielsweise ohne Klammern angegeben:
addEventListener(MouseEvent.CLICK, clickHandler)
Mit dem Parameter
useCapture
der
addEventListener()
-Methode können Sie die Ereignisablaufphase festlegen, in der der Listener aktiv ist. Wenn
useCapture
den Wert
true
hat, ist der Listener während der Empfangsphase des Ereignisablaufs aktiv. Wenn
useCapture
den Wert
false
hat, ist der Listener während der Zielphase und der Aufstiegsphase des Ereignisablaufs aktiv. Damit in allen Phasen des Ereignisablaufs auf das Ereignis gewartet wird, müssen Sie
addEventListener()
zweimal aufrufen: einmal mit
useCapture
für den Wert
true
und einmal mit
useCapture
für den Wert
false
.
Der Parameter
priority
der
addEventListener()
-Methode ist kein offizieller Bestandteil des DOM3-Ereignismodells. Er wurde in ActionScript 3.0 aufgenommen, um eine höhere Flexibilität beim Organisieren von Ereignis-Listenern zu ermöglichen. Beim Aufrufen von
addEventListener()
können Sie die Priorität des jeweiligen Ereignis-Listeners festlegen, indem Sie als
priority
-Parameter einen Ganzzahlwert übergeben. Der Standardwert ist 0. Sie können jedoch sowohl negative als auch positive Werte angeben. Je größer die Zahl ist, desto eher wird der entsprechende Ereignis-Listener abgearbeitet. Ereignis-Listener mit derselben Priorität werden in der Reihenfolge des Hinzufügens abgearbeitet. Je eher ein Listener hinzugefügt wurde, desto eher wird er auch abgearbeitet.
Mit dem Parameter
useWeakReference
können Sie festlegen, ob es sich um einen schwachen oder normalen Verweis auf die Listener-Funktion handelt. Durch Festlegen von
true
für diesen Parameter können Sie Situationen vermeiden, in denen Listener-Funktionen im Speicher zurückbleiben, auch wenn sie nicht mehr benötigt werden. In Flash Player und AIR wird ein Verfahren mit der Bezeichnung
Garbage Collection
(automatische Speicherbereinigung) verwendet, um nicht mehr verwendete Objekte aus dem Speicher zu entfernen. Objekte gelten als nicht mehr verwendet, wenn keine Verweise auf sie vorhanden sind. Bei der Speicherbereinigung werden schwache Verweise nicht berücksichtigt. Das bedeutet, dass Listener-Funktionen mit ausschließlich schwachen Verweisen bei der Speicherbereinigung entfernt werden.
Entfernen von Ereignisprozeduren
Mit der
removeEventListener()
-Methode können Sie einen Ereignis-Listener entfernen, den Sie nicht mehr benötigen. Es empfiehlt sich, alle nicht mehr benötigten Listener zu entfernen. Erforderliche Parameter sind
eventName
und
listener
, die identisch sind mit den erforderlichen Parametern für die
addEventListener()
-Methode. Rufen Sie sich in Erinnerung, dass in allen Phasen des Ereignisablaufs auf das Ereignis gewartet werden kann, wenn Sie
addEventListener()
zweimal aufrufen: einmal mit dem Wert
true
für
useCapture
und einmal mit dem Wert
false
. Damit beide Ereignis-Listener wieder entfernt werden, müssen Sie
removeEventListener()
ebenfalls zweimal aufrufen: einmal mit dem Wert
true
für
useCapture
und einmal mit dem Wert
false
.
Auslösen von Ereignissen
Erfahrene Programmierer können die
dispatchEvent()
-Methode einsetzen, um ein benutzerdefiniertes Ereignisobjekt in den Ereignisablauf einzufügen. Der einzige für diese Methode zulässige Parameter ist ein Verweis auf ein Ereignisobjekt, das eine Instanz der Event-Klasse oder einer ihrer Unterklassen sein muss. Nach dem Auslösen des Ereignisses ist als
target
-Eigenschaft des Ereignisobjekts das Objekt eingetragen, für das
dispatchEvent()
aufgerufen wurde.
Überprüfen auf vorhandene Ereignis-Listener
Die letzten beiden Methoden der IEventDispatcher-Schnittstelle stellen nützliche Informationen über das Vorhandensein von Ereignis-Listenern bereit. Die
hasEventListener()
-Methode gibt
true
zurück, wenn für einen bestimmten Ereignistyp und das angegebene Anzeigelistenobjekt ein Ereignis-Listener gefunden wurde. Die
willTrigger()
-Methode gibt ebenfalls
true
zurück, wenn für ein bestimmtes Anzeigelistenobjekt ein Ereignis-Listener gefunden wurde. Bei
willTrigger()
wird jedoch nicht nur dieses eine Objekt in der Anzeigeliste überprüft, sondern für alle Phasen des Ereignisablaufs auch alle Vorgänger dieses Objekts.
Fehlerereignisse ohne Listener
Der primäre Mechanismus für die Fehlerverarbeitung in ActionScript 3.0 sind nicht Ereignisse, sondern Ausnahmen. Die Ausnahmenverarbeitung funktioniert jedoch nicht bei asynchronen Vorgängen, z. B. beim Laden von Dateien. Wenn während eines asynchronen Vorgangs ein Fehler auftritt, wird in Flash Player und AIR ein Fehlerereignisobjekt ausgelöst. Wenn Sie keinen Listener für dieses Fehlerereignis erstellt haben, wird in der Debugger-Versionen von Flash Player und AIR ein Dialogfeld mit Informationen zum Fehler angezeigt. In der Debugger-Version von Flash Player wird beispielsweise das folgende Dialogfeld mit einer Fehlerbeschreibung angezeigt, wenn die Anwendung versucht, eine Datei von einer ungültigen URL zu laden:
Die meisten Fehlerereignisse basieren auf der ErrorEvent-Klasse und verfügen daher über eine
text
-Eigenschaft, die zum Speichern der in Flash Player oder AIR angezeigten Fehlermeldung verwendet wird. Die beiden Ausnahmen sind die StatusEvent- und die NetStatusEvent-Klasse. Beide Klassen verfügen über eine
level
-Eigenschaft (
StatusEvent.level
und
NetStatusEvent.info.level
). Wenn diese
level
-Eigenschaft den Wert
error
aufweist, wird bei diesen Ereignistypen von Fehlerereignissen ausgegangen.
Fehlerereignisse führen nicht zum Abbruch der Ausführung einer SWF-Datei. Sie manifestieren sich nur als Dialogfelder in den Debugger-Versionen des Browser-Plug-Ins und des eigenständigen Players, als Meldung im Bedienfeld „Ausgabe“ des Authoring-Players und als Eintrag in der Protokolldatei für Adobe Flash Builder. In den normalen Versionen von Flash Player bzw. AIR werden Fehlerereignisse in keiner Form angezeigt.
|
|
|