Ereignis-Listener

Flash Player 9 und höher, Adobe AIR 1.0 und höher

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.