flash event_model_sub-classes
The Event sub-classes
When the Event.ENTER_FRAME is broadcast, the Event type event object has no supplementary information to send to the listener. The communal target and type properties are sufficient.
On the other hand, if you want to listen to a keyboard instigated event, there is a strong chance that our listener needs supplementary information, for example the keyboard key that has just been typed and which has provoked the broadcast of this event. In the same way, an event broadcast by the mouse can advise us on its position or even on which element our curser is situated over.
If we look at definition of the MouseEvent class we discover new properties containing the information that we could need.
The following code gets the mouse position as well as the state of the ALT key on the keyboard:
myButton.addEventListener ( MouseEvent.CLICK, clickButton ); function clickButton ( pEvt:MouseEvent ):void { // display : x : 40.05 y : 124.45 trace ( "x : " + pEvt.stageX + " y : " + pEvt.stageY ); // display : x : 3 y : 4 trace ( "x : " + pEvt.localX + " y : " + pEvt.localY ); // display : ALT pressed : false trace ( "ALT pressed : " + pEvt.altKey ); }
When the MouseEvent.CLICK event is broadcast, the clickButton listener function is notified and gets information relative to the event within the event object, in this case the MouseEvent type.
We get here the mouse position in relation to the stage by targeting the stageX and stageY properties, the altKey property is a Boolean advising on the state of the ALT key.
The localX and localY properties of the pEvt event we advise on the mouse position compared to the local reference mark of the button, which gives us a great level of accuracy of the coordinates of the mouse.
When examining the other sub-classes of the Event class you discover that each sub-class integrates supplementary properties advising on the state of the event object source.
Worth remembering
- All objects in the Flash package can broadcast events.
- The addEventListener method is the only way to listen to an event.
- The name of each event is stored in the static property of the class corresponding to the event in question.
- When an event is broadcast it send an event object to the listener function as a parameter.
- The type of event object is the same as the class containing the event name.
- An event object possesses at least a target and currentTarget property corresponding to the target object and to the author event object. The type property allows you to know the event name being broadcast.
Stopping the listening of an event
Imagine that you no longer want to know the latest DVD releases at your video club. By informing the manager of the shop that you no longer want to be notified, you will no longer be a listener to the ânew DVDâ event.
In ActionScript 3, when we no longer want to listen to an event, we use the removeEventListener method. Here is the signature:
removeEventListener(type: <code actionscript> String, listener:Function, useCapture:Boolean = false):void
The first parameter called type is waiting for the event name that we want to unsubscribe from, the second parameter is waiting for a reference to the listener function. This second parameter is discussed in the article Event Propagation.
Letâs look at this example. When a button is clicked, the MouseEvent.CLICK event is broadcast, the clickButton listener function is notified and we delete the event listener:
myButton.addEventListener( MouseEvent.CLICK, clickButton ); function clickButton ( pEvt:MouseEvent ):void { // display : x : 40.05 y : 124.45 trace( "x : " + pEvt.stageX + " y : " + pEvt.stageY ); // display : ALT pressed : false trace( "ALT pressed : " + pEvt.altKey ); // we delete the listener of the MouseEvent.CLICK event pEvt.target.removeEventListener ( MouseEvent.CLICK, clickButton ); }
Calling the removeEventListener method on the myButton object within the clickButton listener function deletes the listener of the MouseEvent.CLICK event. The listener function will therefore be triggered once only.
When you no longer need a listener remember to delete it from the listener list using the removeEventListener method. The garbage collector wonât delete an object with one of these methods saved as a listener. To optimize your application, remember to delete the unused listeners, you will use less memory and you will be safe from difficult to diagnose problems.
Putting it into practice
In order to put the previous theories into practice letâs create a project in which a window will open with an inertia effect controlled by randomly evaluated dimensions. Once the movement has finished we delete the necessary event in order to free up resources and to optimise the execution of our project. In a Flash document, we create an occurrence of the clip myWindow representing a solid colour rectangle.
We listen to the MouseEvent.CLICK event on a button called myButton also placed on the stage:
myButton.addEventListener ( MouseEvent.CLICK, clickButton );
Then we define a listener function:
function clickButton ( pEvt:MouseEvent ):void { trace("listener function triggered"); }
When the myButton button is clicked, the listener function clickButton is triggered and we display the execution validation message. We do however need to define the Event.ENTER_FRAME event on our myWindow clip. You can modify the clickButton function in the following way:
function clickButton ( pEvt:MouseEvent ):void { trace("listener function triggered"); trace("subscription of the Event.ENTER_FRAME event"); myWindow.addEventListener ( Event.ENTER_FRAME, resize ); }
When calling the addEventListener method on our myWindow clip, we subscribe the resize listener function which allows for the re-dimensioning of our clip. We then define the resize function:
function resize ( pEvt:Event ):void { trace("execution of the resize function"); }
We get the following code:
myButton.addEventListener ( MouseEvent.CLICK, clickButton ); function clickButton ( pEvt:MouseEvent ):void { trace("listener function triggered"); trace("subscription of the Event.ENTER_FRAME event"); myWindow.addEventListener ( Event.ENTER_FRAME, resize ); } function resize ( pEvt:Event ):void { trace("execution of the resize function"); }
When the mouse is clicked, the message âexecution of the resize functionâ is displayed. Letâs add the inertia effect to resize the window.
Firstly we need to generate a random size. To do this we define two variables on our timeline in order to store the height and width generated randomly. Just after the MouseEvent.CLICK event we define two variables - width and height:
var width:Number; var height:Number;
These two variables will allow us to store the height and width that we will generate randomly with each mouse click. We will evaluate these sizes with the clickButton function by allocating these two variables:
function clickButton ( pEvt:MouseEvent ):void { width = Math.random()*400; height = Math.random()*400; trace("listener function triggered"); trace("subscription of the Event.ENTER_FRAME event"); myWindow.addEventListener ( Event.ENTER_FRAME, resize ); }
We use the random method of the Math class in order to evaluate a random size on the height and width in magnitudes of 400 pixels. In this case we will choose a magnitude which is smaller than the total size of the stage. We modify the resize function in order to add the desired effect:
function resize ( pEvt:Event ):void { trace("execution of the resize function"); myWindow.width -= ( myWindow.width â width ) * .3; myWindow.height -= ( myWindow.height - height ) * .3; }
Letâs refresh our memory by reading this code:
myButton.addEventListener ( MouseEvent.CLICK, clickButton ); var width:Number; var height:Number; function clickButton ( pEvt:MouseEvent ):void { width = Math.random()*400; height = Math.random()*400; trace("listener function triggered"); trace("subscription of the Event.ENTER_FRAME event"); myWindow.addEventListener ( Event.ENTER_FRAME, resize ); } function resize ( pEvt:Event ):void { trace("execution of the resize function"); myWindow.width -= ( myWindow.width - width ) *.3; myWindow.height -= ( myWindow.height - height ) *.3; }
When we click on the myButton button, our window resizes to a random size, the effect is fantastic but bear in mind that we never stop listening to the Event.ENTER_FRAME event!
In consequence, each click on the myButton button activates the resize function as a listener alongside the Event.ENTER_FRAME event which is useless and can use up resources.
In order to avoid adding a listener to an event that is already listened to we use the hasEventListener method. Here is its signature:
hasEventListener(type: String):Boolean
This method accepts the name parameter as an event and sends a boolean indicating if the event is listened to or not. We modify the clickButton function in order to avoid adding multiple listneres to the event Event.ENTER_FRAME:
function clickButton ( pEvt:MouseEvent ):void { width = Math.random()*400; height = Math.random()*400; trace("listener function triggered"); trace("subscription of the Event.ENTER_FRAME event"); if ( !myWindow.hasEventListener ( Event.ENTER_FRAME ) ) { myWindow.addEventListener ( Event.ENTER_FRAME, resize ); } }
If we leave the code like this, even if the window movement finishes our listener resize function would continue to execute and would use up memory and would slow down our application.
The question that we should therefore ask is: When should we delete the Event.ENTER_FRAME event?
The answer is to test the difference between the current width and height and the final width and height. If the difference is less than a half we can deduct that we have arrived at a satisfactory result, and we can therefore delete the Event.ENTER_FRAME event.
In order to express that in our code, we did this condition to the function resize:
function resize ( pEvt:Event ):void { trace("execution of the resize function"); myWindow.width -= ( myWindow.width - width ) * .3; myWindow.height -= ( myWindow.height - height ) * .3; if ( Math.abs ( myWindow.width - width ) < .5 && Math.abs ( myWindow.height - height ) < .5 ) { myWindow.removeEventListener ( Event.ENTER_FRAME, resize ); trace("resizeing finished"); } }
We delete the Event.ENTER_FRAME event listener with the help of the removeEventListener method. The resize function is no longer executed; we can therefore optimize the memory and the execution performances of our application.
Our application works perfectly, although one essential point has been missed, we have not benefited from any functionality of the new event model.
The coupling between our objects is strong, which shows that a change to an object can bring about modifications to the chain in our code. Letâs see how to fix that by optimizing our relations between objects.
Worth remembering
- The hasEventListener method allows you to know if an event is listened to.
- When an event is no longer used, think about stopping the listener with the help of the removeEventListener method.
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


