Handling Events
Knowing how to handle an event is very important. Just the fact that an event occurs doesn't mean anything in itself. In order to do something with that event, you must capture it first. Flash has two basic means of capturing events: the callback and the listener.The first one we will discuss is the callback.
The Callback
For those who have been programming in Flash for some time, callbacks will seem more familiar and therefore easier to use and implement in your code. Callbacks , simply put, are functions tied directly to a particular event.Because you can create and destroy as well as overwrite any and every variable, function, and method in Flash on the fly, callbacks are basically functions written directly to the event.For instance, the movie clip object has an event called onMouseDown that is triggered every time the user presses the mouse button on the stage. But if you were to run a blank movie (remember, the main timeline is nothing more than the _root movie clip) and click the mouse on the stage, nothing would happen. This is because no function has been created with the onMouseDown event.So to handle the event, you need to build a function around the event itself like this:
Usually you would want to do more than simply send a message to the Output panel. Sometimes, you may want the event to interact with other objects, and that's where the downside of callbacks comes in.Because callbacks are associated directly with events of a specific object, in this case the _root timeline, you cannot always refer directly to other objects on the stage if they are not enclosed in the object of the event being called.For instance, if you have two movie clips on the stage (movie1_mc and movie2_mc), and you have a onMouseDown event for the movie1_mc movie, you cannot directly access movie2_mc from within that event:
//this refers to the main timeline
this.onMouseDown = function(){
trace("the mouse is down");
}
The preceding code will not run properly because the onMouseDown event is in the scope of the movie1_mc and not in the scope of movie2_mc. The following code will fix this problem.
movie1_mc.onMouseDown = function(){
movie2_mc.gotoAndPlay("start"); //this will not work
}
Just keep in mind the scope of the object you are referring to inside the event.Another point to note is that some events pass information to the callback. For instance, the onLoad event for the LoadVars object sends the callback a Boolean value based on its success or failure in loading content.Here's an example of how to get information from events with callbacks:
movie1_mc.onMouseDown = function(){
_parent.movie2_mc.gotoAndPlay("start"); //this will work
}
Notice that we passed the information coming from the event as a parameter in the function. That's how we get information from events using callbacks. And in this case, the event is a Boolean value that is used in conjunction with conditional statements inside the event.Now that you see how to create a callback, it is important to know how to destroy them as well.
//create the LoadVars object
var myStuff:LoadVars = new LoadVars();
//create the call back
myStuff.onLoad = function(success){
if(success){
//it worked
}else{
//it didn't work
}
}
//load the content
myStuff.load("theStuff.txt");
Removing Callbacks
Sometimes you will want callbacks to stop firing. For instance, if you are using a callback in conjunction with the onEnterFrame event of movie clips, you may only want that event to fire so many times. You can use conditionals to stop the event from affecting anything on the stage, but to regain processor power and virtual memory you need to destroy the callback itself. To do this, you use the delete action.Here is an example using a loop statement and a delete action:
The preceding code first creates a variable that is used in the callback. Then it creates the callback and uses a conditional to decide when to destroy itself with the delete action.Run this code, and you should see an Output panel similar to Figure 14.1. The code runs ten times and then stops completely. To see what would happen if the delete action had not been used, just the conditional, go back and comment out the line containing the delete action. You will see that even though the numbers stop being sent to the Output panel (because of the conditional), the other trace action is still working because the event is still triggering the callback.
//create a variable we will use in the callback
var i:Number = 0;
//create the callback
this.onEnterFrame = function(){
//this will trace independant of the conditional
trace("working");
if(i < 10){
trace(i);
}else{
delete this.onEnterFrame;
}
//increase the variable
i++;
}
Figure 14.1. Use the delete action to destroy callbacks.

Listeners
If you are new to programming, listeners may appear difficult to use at first, but they are quite powerful when you get used to building them. Listeners take a completely different approach to handling events than callbacks do.Listeners differ from callbacks in two very important ways. First, listeners do not care where the event is coming from (that is, a movie clip, button, or component)they only care about who is receiving the event. In the case of the onMouseDown event, the event is coming from the _root timeline, but the Mouse object is actually receiving the event. The other way listeners differ from callbacks is that using a callback with an event will only work with that object, but with listeners, which are objects themselves, you can have several objects "listening" at the same time for the event to fire.Using listeners is also different from using callbacks. Unlike callbacks, where you just apply a function to that object's event, listeners require you to "subscribe" to the event or object containing the event, or "unsubscribe" from the event or object containing the event. This means that you ask the object to let you know when the event occurs, or you tell it to stop letting you know.Not all objects support listeners for their events. Those objects that do support listeners have two methods, addListener() and removeListener(). These two methods are how other objects "subscribe" and "unsubscribe" to the events.Here is an example using the Mouse object's event onMouseDown:
All the preceding code does is create a generic object to "listen" for the event. It adds the event to the object (it looks like a callback, but without the listener, it won't work). Then the last line subscribes the object to the Mouse object as a listener.Now if you test this code, every time the mouse is pressed, the message will be sent to the Output panel.Also, remember that multiple objects can listen to a single event source. In this next example of code, we will extend the preceding example by creating another object to listen for when the mouse is released:
//create the object to listen
var listenClick:Object = new Object();
//create the event that looks similar to callback
listenClick.onMouseDown = function(){
trace("the mouse is down");
}
//now subscribe the listener
Mouse.addListener(listenClick);
This code merely extends the preceding block of code. It creates another object that will listen to the onMouseUp Mouse event. And then we subscribe it to the Mouse object.Every time you press and release the mouse button, you will receive two messages in the Output window as shown in Figure 14.2.
//create the object to listen
var listenClick:Object = new Object();
//create the event that looks similar to callback
listenClick.onMouseDown = function(){
trace("the mouse is down");
}
//now subscribe the listener
Mouse.addListener(listenClick);
//create another object
var listenUp:Object = new Object();
//create the event similar to before
listenUp.onMouseUp = function(){
trace("and the mouse is back up again");
}
//now add the new object to the event source as a listener
Mouse.addListener(listenUp);
Figure 14.2. Using listeners can increase efficiency for capturing events.

When you test this out, it will work exactly the same way as before.Now that you know how to subscribe listeners to objects, the next section shows how to unsubscribe them.
//create the object to listen
var mouseListen:Object = new Object();
//create the event that looks similar to callback
mouseListen.onMouseDown = function(){
trace("the mouse is down");
}
//create the event similar to before
mouseListen.onMouseUp = function(){
trace("and the mouse is back up again");
}
//now add the object to the event source as a listener
Mouse.addListener(mouseListen);
Unsubscribing Listeners
Unsubscribing an object uses the method removeListener() in conjunction with the object it is currently listening to. This example shows how to use this method:
This code starts the same way the preceding code does, but the first time the event fires, the listening object removes itself from the Mouse object. After the first click, no messages will be sent to the Output panel.Components also use listeners to trigger events associated with them, although the coding is slightly different from what we have used so far.
//create the object to listen
var listenClick:Object = new Object();
//create the event that looks similar to callback
listenClick.onMouseDown = function(){
//send a message to the output panel
trace("the mouse is down");
//remove the listener
Mouse.removeListener(this);
}
//now subscribe the listener
Mouse.addListener(listenClick);
Components' Special Listeners
Way back in Flash MX, components used a form of callbacks to refer to functions on the timeline of which the component itself resided. However, with the introduction of ActionScript 2.0, components' events are now centered on using listeners.To add listeners to components, you use the component's instance name and the addEventListener() method.The generic layout of the addEventListener() method is as follows:
This method has two parameters:
component.addEventListener(event, listenerObject);
- event
A string literal representing the event you want to listen for - listenerObject
The object being added as a listener
Here is an example of how to add an event listener to the button component:
1. | Create a new Flash document. |
2. | Drag an instance of the Button component onto the stage. |
3. | Give the button an instance name of myButton . |
4. | Create a new layer and name it actions . |
5. | In the actions layer, open the Actions panel, and place the following code within it:
|
The preceding code creates a listener object. Then it creates the event-handling method for that object, which has a trace function in it so it will send a message to the Output panel. Then you add the event listener to the instance of the button.Now test the movie, and you will see that every time you click the button, the event is triggered, and the listener fires, sending a message to the Output panel.You can create your own events with components, but that is discussed in more detail in Chapter 16, "Components." And even though component events are centered around listeners, they do have a few hidden callbacks built into them as the next example shows.Continuing from the previous example, replace the code in the actions layer with the following:
Run the above example, and again a message will be sent to the Output panel.But not every listener event in components is as easy as this one, but in general, you can use the event name, in the above case "click," and add "Handler" to it to create a callback. Another example of this is the changeHandler callback for the ComboBox and List component.And sometimes with callbacks and listeners being triggered all over your code, you might be accidentally duplicating your work.
//create the callback
myButton.clickHandler = function(){
trace("the button was clicked, again");
}
Duplicating Effort
Some objects will support both callbacks as well as listeners. For instance, you can create a callback with the onMouseDown event and then add a listener to the Mouse object at the same time. Doing this will produce some surprising results, as you will see in the next example of code.
The code creates the callback that we have been using in this chapter. After that, it adds the _root timeline as a listener to the Mouse object.Now test the movie, and you will see that every time you press the mouse button on the stage, the message appears twice in the Output panel. Keep this in mind when dealing with both callbacks and listeners.Now you have seen the two ways Flash handles events, and I bet you are wondering which one you should use.
//create the callback
this.onMouseDown = function(){
trace("the mouse is down");
}
//Now add the listener to the Mouse object
Mouse.addListener(this);
Callbacks Versus ListenersThe Showdown
We have covered both sides of capturing events, the callbacks and the listeners. Now comes the moment of truthwhich one should you use in which situation? Well, if the truth be told, most of the time the choice is already made for you. Most of Flash's built-in object classes support either callbacks or listeners. A few, however, do support both.