Inspelnings- och bubblingshändelser

Använd inspelnings- och bubblingshändelser för att minimera händelsehanterare.

Med händelsemodellen i ActionScript 3.0 introducerades begreppet med inspelnings- och bubblingshändelser. Genom att tillvarata fördelarna med en bubblingshändelse kan du få hjälp med att optimera ActionScript-kodens körningstid. Du kan registrera en händelsehanterare för ett objekt, i stället för flera objekt, för att få bättre prestanda.

Tänk dig ett spel där användaren måste klicka på äpplen så snabbt som möjligt för att förstöra dem. I spelet tas varje äpple som användaren klickat på bort från skärmen och ny poäng läggs till i resultatet. För att kunna avlyssna händelsen MouseEvent.CLICK som tar bort äpplet kanske du känner dig frestad att skriva följande kod:

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

I den här koden anropas metoden addEventListener() för varje Apple-instans. Dessutom tas med hjälp av metoden removeEventListener() varje avlyssnare bort när användaren klickar på ett äpple. Händelsemodellen i ActionScript 3.0 erbjuder emellertid en inspelnings- och bubblingsfas för vissa händelser, vilket gör att du kan avlyssna den från ett överordnat InteractiveObject. Det är därför möjligt att optimera koden här ovan och minimera antalet anrop till metoderna addEventListener() och removeEventListener() . I följande kod används inspelningsfasen för att avlyssna händelser från det överordnade objektet.

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

Koden är förenklad och mycket optimerad med endast ett anrop till metoden addEventListener() i den överordnade behållaren. Avlyssnare registreras inte längre i Apple-instansen så det finns inget behov att ta bort dem när användaren klickar på ett äpple. Hanteraren onAppleClick() kan optimeras ytterligare genom att stoppa spridningen av händelsen så att den inte fortsätter:

function onAppleClick ( e:MouseEvent ):void 
{ 
    e.stopPropagation(); 
    currentAppleClicked = e.target as InteractiveObject; 
    container.removeChild ( currentAppleClicked ); 
}

Bubblingsfasen kan även användas för att spela in händelsen genom att skicka false som den tredje parametern till metoden addEventListener() :

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

Standardvärdet för inspelningsfasparametern är false så du kan utelämna den:

container.addEventListener ( MouseEvent.CLICK, onAppleClick );