Mithilfe von Ereigniserfassung und Bubbling lassen sich Ereignisprozeduren reduzieren.
Seit dem Ereignismodell von ActionScript 3.0 stehen die Konzepte „Ereigniserfassung“ und „Ereignis-Bubbling“ zur Verfügung. Das Ereignis-Bubbling bietet die Möglichkeit, die Ausführungszeit des ActionScript-Codes zu optimieren. Sie können eine Ereignisprozedur für ein Objekt anstelle für mehrere Objekte registrieren, um die Leistung zu verbessern.
Dies lässt sich anhand eines Spiels erläutern, in dem der Anwender so schnell wie möglich auf Äpfel klicken muss, um sie zu zerstören. Bei jedem Klicken auf einen Apfel wird dieser vom Bildschirm entfernt und der Anwender erhält Punkte. Zum Warten auf das von den einzelnen Äpfeln ausgelöste
MouseEvent.CLICK
-Ereignis mag der folgende Code geeignet erscheinen:
const MAX_NUM:int = 10;
var sceneWidth:int = stage.stageWidth;
var sceneHeight:int = stage.stageHeight;
var currentApple:InteractiveObject;
var currentAppleClicked:InteractiveObject;
for ( var i:int = 0; i< MAX_NUM; i++ )
{
currentApple = new Apple();
currentApple.x = Math.random()*sceneWidth;
currentApple.y = Math.random()*sceneHeight;
addChild ( currentApple );
// Listen to the MouseEvent.CLICK event
currentApple.addEventListener ( MouseEvent.CLICK, onAppleClick );
}
function onAppleClick ( e:MouseEvent ):void
{
currentAppleClicked = e.currentTarget as InteractiveObject;
currentAppleClicked.removeEventListener(MouseEvent.CLICK, onAppleClick );
removeChild ( currentAppleClicked );
}
Der Code ruft die
addEventListener()
-Methode für jede Apple-Instanz auf. Außerdem entfernt er beim Klicken auf einen Apfel den zugehörigen Listener unter Verwendung der
removeEventListener()
-Methode. Das Ereignismodell in ActionScript 3.0 bietet jedoch eine Erfassungs- und Bubbling-Phase für einige Ereignisse, sodass Sie über ein übergeordnetes InteractiveObject auf diese Ereignisse warten können. Deshalb ist es möglich, den oben gezeigten Code zu optimieren und die Methoden
addEventListener()
und
removeEventListener()
weniger oft aufzurufen. Der folgende Code verwendet die Erfassungsphase, um auf die Ereignisse vom übergeordneten Objekt zu warten:
const MAX_NUM:int = 10;
var sceneWidth:int = stage.stageWidth;
var sceneHeight:int = stage.stageHeight;
var currentApple:InteractiveObject;
var currentAppleClicked:InteractiveObject;
var container:Sprite = new Sprite();
addChild ( container );
// Listen to the MouseEvent.CLICK on the apple's parent
// Passing true as third parameter catches the event during its capture phase
container.addEventListener ( MouseEvent.CLICK, onAppleClick, true );
for ( var i:int = 0; i< MAX_NUM; i++ )
{
currentApple = new Apple();
currentApple.x = Math.random()*sceneWidth;
currentApple.y = Math.random()*sceneHeight;
container.addChild ( currentApple );
}
function onAppleClick ( e:MouseEvent ):void
{
currentAppleClicked = e.target as InteractiveObject;
container.removeChild ( currentAppleClicked );
}
Dieser optimierte Code ist wesentlich einfacher und erfordert nur einen Aufruf der
addEventListener()
-Methode für den übergeordneten Container. Da keine Listener mehr für die Apple-Instanzen registriert sind, müssen sie beim Klicken auf einen Apfel auch nicht mehr entfernt werden. Die
onAppleClick()
-Prozedur kann noch weiter optimiert werden, indem die Fortsetzung des Ereignisses gestoppt wird:
function onAppleClick ( e:MouseEvent ):void
{
e.stopPropagation();
currentAppleClicked = e.target as InteractiveObject;
container.removeChild ( currentAppleClicked );
}
Auch die Bubbling-Phase kann zum Abfangen des Ereignisses verwendet werden, indem
false
als dritter Parameter an die
addEventListener()
-Methode übergeben wird:
// Listen to the MouseEvent.CLICK on apple's parent
// Passing false as third parameter catches the event during its bubbling phase
container.addEventListener ( MouseEvent.CLICK, onAppleClick, false );
De Standardwert für den Parameter der Erfassungsphase ist
false
; Sie können ihn also weglassen:
container.addEventListener ( MouseEvent.CLICK, onAppleClick );