Die Ereignisobjekt-Eigenschaften bubbles, eventPhase, target, currentTarget

Die Eigenschaft "bubbles"

Im vorigen Kapitel wurde erklärt, dass nicht jedes Ereignisobjekt alle 3 Ereignisphasen des Ereignisablaufs durchläuft.

Jedes Ereignisobjekt, d.h. jede Instanz der Klasse Event, besitzt eine Eigenschaft bubbles, die nur gelesen werden kann.
Wenn bubbles den Wert true hat, dann durchläuft das Ereignisobjekt auch die Aufstiegsphase, sonst nicht.

Beispiel:

Mausereignis-Objekte vom Typ ROLL_OVER und ROLL_OUT haben keine Aufstiegsphase. Alle anderen Mausereignisse haben sowohl eine Empfangs- als auch eine Aufsteigsphase. Man kann das leicht selbst überprüfen:
Erstellen Sie auf der Bühne eine beliebige Movieclip-Instanz und geben dieser den Namen myClip.
Anschließend fügen Sie nachfolgendes Skript in das erste Frame der Timeline ein.
 

myClip.addEventListener(MouseEvent.ROLL_OVER,bubbleTest);
function bubbleTest(e:MouseEvent):void {
trace(e.bubbles);
}

Bei der entsprechenden Mausaktion wird der Wert von bubbles im Ausgabe-Fenster angezeigt.
Ersetzen Sie nun ROLL_OVER durch beliebige andere Mausereignis-Typen und prüfen die bubbles-Eigenschaft.
 

Die Eigenschaften "target" und "currentTarget"

Wenn man z.B. auf ein auf ein Displayobjekt, das auf der Bühne liegt, klickt, wird ein Mausereignis-Objekt vom Typ CLICK an die Displayliste weiter gegeben und durchläuft den Baum von der Bühne bis zu dem angeklickten Dispalyobjekt (= Zielobjekt) und wieder retour.
Wenn die Displayobjekte, die auf dem Weg zum Zielobjekt liegen, das click-Ereignis abonniert haben, wird der dazugehörigen EventListener aufgerufen. Daher müssen das Zielobjekt und das Objekt, das den EventListener aufruft, nicht übereinstimmen.

Um diesen Unterschied abfragen zu können, gibt es die Ereignisobjekteigenschaften target und currentTarget:
Über die Ereignisobjekteigenschaft target kann man immer das Zielobjekt des Ereignisses abfragen und
die Eigenschaft currentTarget liefert dem Eventlistener das Objek, das den Listener tatsächlich aufgerufen hat.

Beispiel:

Drei Movieclipinstanzen blau, gelb und rot liegen ineinander geschachtelt auf der Bühne.

Im ersten Frame der Maintimeline wird nachfolgendes Skript eingefügt, in dem sich die Bühne mit den EventListener showTarget beim mouseDown-Ereignis registriert. Der EventListener gibt im Ausgabe-Fenster die Namen der target- und currentTarget-Objekte aus.
 

this.stage.addEventListener(MouseEvent.MOUSE_DOWN, showTarget);

function showTarget(event:MouseEvent):void {
trace("target: "+event.target.name+" currentTarget: "+event.currentTarget.name);
}

Klickt man nun im Fenster des Flash-Players, dann liefert das Ausgabefenster:

Klick auf ...
Text im Ausgabefenster
weiße Fläche der Bühne
target: null   currentTarget: nul
rote Fläche
target: rot    currentTarget: null
gelbe Fläche
target: gelb   currentTarget: null
blaue Fläche
target: blau   currentTarget: null

Anmerkung: Da der Bühne kein Name zugeordnet ist, wird der Wert null für die Bühne ausgegeben.
currentTarget liefert immer die Bühne, da nur die Bühne einen EventListener registriert hat. target ändert sich jedoch, je nachdem worauf man geklickt hat.

Im nachfolgenden Video wird das  Beispiel zusammengefasst:
 

 

 

In welcher der drei Phasen wird ein Eventhandler ausgeführt?

Da man einen Eventlistener (Eventhandler) nicht nur dem Zielknoten, sondern auch jedem beliebigen Knoten entlang des Ereignisablaufs hinzufügen kann und dieser sowohl in der Empfangsphase als auch in der Aufstiegsphase durchlaufen wird, stellt sich die Frage, wann der Event-Handler ausgeführt wird.

Im ersten Kapitel wurde das Grundschema für das Registrieren eines Eventlisteners vorgestellt:
 

eventTarget.addEventListener(EventType.EVENT_NAME, eventListener);
 
Dabei wurde ein dritter möglicher Parameter useCapture von addEventListener weggelassen, der festlegt, ob der Eventlistener in der Empfangs- oder Aufstiegsphase ausgeführt wird.
 
eventTarget.addEventListener(EventType.EVENT_NAME, eventListener, useCapture);

Der Standardwert ist false, d.h. wenn man diesen Parameter nicht schreibt, ist der Wert false.
false
bedeutet, dass der Listener das Ereignis nur während der Ziel- oder Bubbling-Phase verarbeitet. D.h. standardmäßig wird zuerst (falls es einen gibt) der Eventlistener des Zielobjekts abgearbeitet und anschließend (falls registriert) die Eventlistener der übergeordneten Objekte.

true bedeutet, dass der Listener das Ereignis nur während der Empfangsphase und nicht während der Ziel- oder Bubbling-Phase verarbeitet. D.h. der Eventlistener des Zielobjekts wird nicht abgearbeitet.

Damit das Ereignis in allen drei Phasen aktiv ist, ruft man addEventListener() zweimal auf. Einmal ist useCapture auf true gesetzt, und beim zweiten Mal hat useCapture den Wert false
 

Die Eigenschaft "eventPhase"

Die drei Ereignisphasen werden in ActionScript 3.0 durch folgende drei Konstante beschrieben:

 Empfangsphase: EventPhase.CAPTURING_PHASE diese Konstante hat den Wert 1
 Zielphase: EventPhase.AT_TARGET
 diese Konstante hat den Wert 2
 Aufstiegsphase: EventPhase.BUBBLING_PHASE diese Konstante hat den Wert 3

Über die Eigenschaft eventPhase eines Ereignisobjekts kann festgestellt werden, in welcher der 3 Ereignisphasen des Ereignisablaufs der Eventlistener aufgerufen wurde. eventPhase liefert in Übereinstimmung zu den obigen Konstanten den Wert 1, 2 oder 3.
Sei event ein Ereignisobjekt, dann kann über einen der nachfolgenden Vergleiche eine Ereignisphase abgefragt und entsprechend darauf reagiert werden:
 

if (event.eventPhase == EventPhase.CAPTURING_PHASE) { ... }
if (event.eventPhase == EventPhase.AT_TARGET) { ... }
if (event.eventPhase == EventPhase.BUBBLING_PHASE) { ... }

 
Beispiel:

Wir verwenden noch einmal das Beispiel von oben und registrieren die Bühne, die Maintimeline und alle drei Movieclips sowohl für die Empfangsphase, als auch für die Ziel- und Aufstiegsphase beim mouseDown-Ereignis mit demselben Eventlistener, der im Ausgabe-Fenster die Eigenschaften target, currentTarget und eventPhase ausgibt.

Im ersten Frame der Maintimeline steht folgendes Skript:
 

this.addEventListener(MouseEvent.MOUSE_DOWN, eventFlow, false); // für Ziel- und Aufstiegsphase  
this.addEventListener(MouseEvent.MOUSE_DOWN, eventFlow, true); // für Empfangsphase
this.stage.addEventListener(MouseEvent.MOUSE_DOWN, eventFlow, false); // für Ziel- und Aufstiegsphase
this.stage.addEventListener(MouseEvent.MOUSE_DOWN, eventFlow, true); // für Empfangsphase
this.rot.addEventListener(MouseEvent.MOUSE_DOWN, eventFlow, false); // für Ziel- und Aufstiegsphase
this.rot.addEventListener(MouseEvent.MOUSE_DOWN, eventFlow, true); // für Empfangsphase
this.rot.gelb.addEventListener(MouseEvent.MOUSE_DOWN, eventFlow, false); // für Ziel- und Aufstiegsphase
this.rot.gelb.addEventListener(MouseEvent.MOUSE_DOWN, eventFlow, true); // für Empfangsphase
this.rot.gelb.blau.addEventListener(MouseEvent.MOUSE_DOWN, eventFlow, false); // für Ziel- und Aufstiegsphase
this.rot.gelb.blau.addEventListener(MouseEvent.MOUSE_DOWN, eventFlow, true); // für Empfangsphase

function eventFlow(event:MouseEvent):void {
trace("target:"+event.target.name+" currentTarget:"+event.currentTarget.name+" Phase: "+event.eventPhase);
}
 

Klickt man nun im Fenster des Flash-Players, dann liefert das Ausgabefenster:
 

Klick auf ...
Text im Ausgabefenster (Phase 2 = Zielphase wurde besonders gekennzeichnet)
weiße Fläche der Bühne
target: null   currentTarget: null   Phase: 2
rote Fläche
target: rot    currentTarget: null   Phase: 1
target: rot    currentTarget: root1  Phase: 1
target: rot    currentTarget: rot    Phase: 2
target: rot    currentTarget: root1  Phase: 3
target: rot    currentTarget: null   Phase: 3
gelbe Fläche
target: gelb   currentTarget: null   Phase: 1
target: gelb   currentTarget: root1  Phase: 1
target: gelb   currentTarget: rot    Phase: 1
target: gelb   currentTarget: gelb   Phase: 2
target: gelb   currentTarget: rot    Phase: 3
target: gelb   currentTarget: root1  Phase: 3
target: gelb   currentTarget: null   Phase: 3
blaue Fläche
target: blau   currentTarget: null   Phase: 1
target: blau   currentTarget: root1  Phase: 1
target: blau   currentTarget: rot    Phase: 1
target: blau   currentTarget: gelb   Phase: 1
target: blau   currentTarget: blau   Phase: 2
target: blau   currentTarget: gelb   Phase: 3
target: blau   currentTarget: rot    Phase: 3
target: blau   currentTarget: root1  Phase: 3
target: blau   currentTarget: null   Phase: 3

Anmerkung: root1 steht  für die Maintimeline.

Im nachfolgenden Video wird das Beispiel zusammengefasst. Sie bewegen am besten den Videoslider manuell und studieren die Ergebnisse im Ausagbe-Fenster.