AS3 Quick Tip: Hacking the Event Flow
Sometimes you may find yourself needing to modify the behavior of a component for a user input event. This article will explain how to do so by modifying the event object in-flight, before it's processed by the component. That's right, you can lie and cheat. In code.
Example
Suppose we have a List component for the user to select multiple items from. We have set its allowMultipleSelection
property to true
, which would allow it to have more than one selected items (hence the name). However, this still requires that the user holds down the Ctrl key, while clicking, to select multiple items. When a single selected item is the exception, not the rule, it would be better if we didn't make the user hold the Ctrl key every time!
The component determines whether the user is holding the Ctrl key by examining the ctrlKey
property of the MouseEvent event object. In the above example, we're tricking the component, by making it appear that the Ctrl key is pressed.
Let's look at how this is done...
Step 1: Set Up the Flash Document
If you already know how to create Flash applications (you probably do) you can skip reading this step, but keep in mind that the existence of an instance of a List component is assumed in next steps. Just in case, let's briefly explain the creation of the project.
Create a new FLA (here named htefExample.fla) and a new document class ActionScript file (here named htefExample.as).
Set the properties of the FLA file and link the document class.

The width of the FLA is set to 300, the height to 200 and the 'Class' input field is set to 'htefExample'".
Drag a List component from the Components panel to the Library.

In the Library the List symbol and its assets are contained.
Write the document class (htefExample.as).
1 |
|
2 |
package{ |
3 |
|
4 |
import flash.display.Sprite; |
5 |
|
6 |
import flash.events.MouseEvent; |
7 |
|
8 |
import fl.controls.List; |
9 |
|
10 |
import fl.data.DataProvider; |
11 |
|
12 |
public class htefExample extends Sprite{ |
13 |
|
14 |
private var list:List; |
15 |
|
16 |
function htefExample(){ |
17 |
// create an instance
|
18 |
list = new List(); |
19 |
// and set some properties
|
20 |
list.width = 200; |
21 |
list.x = 50; |
22 |
list.y = (200-list.height)/2; |
23 |
|
24 |
// set allowMultipleSelection
|
25 |
list.allowMultipleSelection = true; |
26 |
|
27 |
// add data
|
28 |
list.dataProvider = new DataProvider([{label:"One", data:1}, |
29 |
{label:"Two", data:2}, |
30 |
{label:"Three", data:3}, |
31 |
{label:"Four", data:4}, |
32 |
{label:"Five", data:5}]); |
33 |
|
34 |
// add to display list
|
35 |
this.addChild(list); |
36 |
|
37 |
}
|
38 |
|
39 |
}
|
40 |
|
41 |
}
|
Step 2: Add an Event Listener to the Capturing Phase
The signature of the addEventListener method is:
addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
To add a listener to the capturing phase, set the third parameter (useCapture) to true.
1 |
|
2 |
list.addEventListener(MouseEvent.CLICK, hackMouseListener, true); |
Step 3: Define the Contents of the Listener Function
In the body of the function, set the ctrlKey
property to true
.
1 |
|
2 |
private function hackMouseListener(e:MouseEvent):void{ |
3 |
// set ctrlKey property
|
4 |
e.ctrlKey = true; |
5 |
}
|
How It Works
Flash Player has a model for dispatching events and calling event listeners called the event flow. For display-related events, the Player doesn't dispatch the event directly to the target object, but instead injects it at the top-level display object: the stage.
We can visualize the event traveling from the stage down the hierarchy to the target object. This is called the capture phase.
At the target, the event is in the target phase.
Then, the event 'bubbles up' back to the stage. This is the bubbling phase.



The Flash Player event flow.
This imaginary trip determines the order in which the listener functions are called. The useCapture
parameter in the addEventListener
method states our desire about which direction we want our function to be activated: on the capturing way down (value: true
) or bubbling way up (value: false
- the default).
What is interesting is the fact that the event object that is passed as an argument to the listener functions is the same one. So, if we change some of its properties, the listeners further down the event flow will get the same object, now modified!
In the example above, when we registered the hackMouseListener
function to use the capture phase, we made sure that we'll get the event on its "way down", so to speak. That function will be called before the list's listeners which are registered to the target/bubbling phase on the component itself. When the list's code inspects the ctrlKey
property it will find that it is set to true
, indicating that the user pressed the Ctrl key.
Or did he?
Conclusion
You now know how to make a List component multi-select with just a simple event listener. You can use this on other list-based components like DataGrid. Don't forget to set the allowMultipleSlection
property.
More importantly, however, is that (hopefully) you've learned something new about the Flash event flow, about the useCapture
parameter, event phases and how to use this marvelous (and a bit unconventional) method to bend events to your needs.
Hope you enjoyed it. Thank you for reading!