Ereigniserfassung und Bubbling

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 );