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