flash propagation_code_optimisation

Optimising the code with the capture phase

In order to show the value of the capture phase we will take a simple ActionScript application where we will listen to the MouseEvent.CLICK event via different buttons. When we click on each one of them we will delete them from the display list.

In a new Flash CS3 document we will create a button symbol in a rectangular shape linked to a Window class by the Linking properties panel.

Then we add multiple instances of it to our main timeline:

// number of windows
var lng:int = 12;
var myWindow:Window;
for ( var i:int = 0; i< lng; i++ )
{
myWindow = new Window();
myWindow.x = 7 + Math.round ( i % 3 ) * ( myWindow.width + 10 );
myWindow.y = 7 + Math.floor ( i / 3 ) * ( myWindow.height + 10 );
addChild ( myWindow );
}

We obtain the following result:

6.3.1.jpg

Our display list could be represented in the following way:

6.3.2.jpg

Each click on an instance of the Window symbol provokes a propagation of the MouseEvent.CLICK event of the Stage object to our main Timeline.

The timeline is therefore notified of each click on our buttons during the capture phase.

As we previously saw, the capture phase shows the value of being able to intercept an event during the descending phase to a parent graphic object.

This therefore allows us to centralize the listening of the MouseEvent.CLICK event by calling the addEventListener method once only.

In the same way, to stop the listening of an event we call the removeEventListener method on the parent graphic object only.

We therefore don’t need to subscribe a listener to each instance of the Window class but only to the main timeline:

// number of windows
var lng:int = 12;
var myWindow:Window;
for ( var i:int = 0; i< lng; i++ )
{
myWindow = new Window();
myWindow.x = 7 + Math.round ( i % 3 ) * ( myWindow.width + 10 );
myWindow.y = 7 + Math.floor ( i / 3 ) * ( myWindow.height + 10 );
addChild ( myWindow );
}
// subscription to the MouseEvent.CLICK event to
// the main timeline for the capture phase
addEventListener ( MouseEvent.CLICK, clickWindow, true );
function clickWindow ( pEvt:MouseEvent ):void
{
// displays : [MouseEvent type="click" bubbles=true cancelable=false
eventPhase=1 localX=85 localY=15 stageX=92 stageY=118 relatedObject=null
ctrlKey=false altKey=false shiftKey=false delta=0]
trace( pEvt );
}

If we had not used the capture phase we would have had to subscribe a listener to each Window symbol.

By adding a listener to the parent object we can capture the event coming from child objects, rendering our code centralized. If the buttons have been deleted we don’t need to call the removeEventListener method on each of them in order to free resources as only the parent is listened to.

If afterwards the buttons are recreated, no supplementary code is necessary.

Beware, by capturing the event on the main timeline we listen to all of the MouseEvent.CLICK interactive child object events. If we only want to listen to the events coming from the instances of the Window class, we then need to isolate them in an object container and proceed to capture events in it.

We therefore prefer the following approach:

// number of windows
var lng:int = 12;
// creation of a container
var containerWindows:Sprite = new Sprite();
// added to the display list
addChild ( containerWindows );
var myWindow:Window;
for ( var i:int = 0; i< lng; i++ )
{
myWindow = new Window();
myWindow.x = 7 + Math.round ( i % 3 ) * ( myWindow.width + 10 );
myWindow.y = 7 + Math.floor ( i / 3 ) * ( myWindow.height + 10 );
containerWindows.addChild ( myWindow );
}
// subscription to the MouseEvent.CLICK event
// of the container for the capture phase
containerWindows.addEventListener ( MouseEvent.CLICK, clickWindow, true );
function clickWindow ( pEvt:MouseEvent ):void
{
// displays : [MouseEvent type="click" bubbles=true cancelable=false
eventPhase=1 localX=119 localY=46 stageX=126 stageY=53 relatedObject=null
ctrlKey=false altKey=false shiftKey=false delta=0]
trace( pEvt );
}

In order to delete the display of each clicked window we add the removeChild instruction in the clickWindow listener function:

function clickWindow ( pEvt:MouseEvent ):void
{
// the instance of the clicked window is deleted from the display
pEvt.currentTarget.removeChild ( DisplayObject ( pEvt.target ) );
}

The target property makes reference to the clicked Window instance, while the currentTarget property references the container.

On each click, the clicked instance is deleted from the display list:

6.3.2.jpg

We are now going to look at the target phase.

Worth remembering

  • Thanks to the capture phase, we subscribe the listener to the parent graphic object in order to capture the events of child objects.
  • Our code is more optimised and more centralised.







Adobe Training center


Mediabox Training Centre © 2000 - 2008 All rights reserved.
Adobe Authorized Training Centre. State convention under number 25 14 02167 14.
Mediabox : SARL au capital de 62.000€ - Activity number: 25 14 02167 14 - SIRET : 493 716 468 00027
MEDIABOX, 102 Avenue des Champs Elysées, 75008 PARIS - Tel. +33(0)2.31.91.96.89 - Fax. +33(0)2.72.68.56.42