Tuesday, May 26, 2009

Flex: event.target versus event.currentTarget

The event system in Flex allows you catch an Event and its instance to get reference to the component that generated the event.

For example if you do make the following declaration in MXML:

<mx:Button click=”clicked(event)” />

When that button is clicked it calls in ActionScript the function “clicked(event:MouseEvent):void”

So how do you get reference to the button that generated the event in that function?

Well, according to the Adobe Event API (http://livedocs.adobe.com/flex/3/langref/flash/events/Event.html) you can use:

  • event.target - The event target. This property contains the target node. For example, if a user clicks an OK button, the target node is the display list node containing that button.
  • event.currentTarget - The object that is actively processing the Event object with an event listener. For example, if a user clicks an OK button, the current target could be the node containing that button or one of its ancestors that has registered an event listener for that event.

So what does that mean and which should I use?

You can’t tell from that description, but I can tell you about a problem I was having with a component displaying lots of buttons. So there was a component with lots of buttons on it, where when a button was pressed it would call a function that would determine which button was pressed and do all sorts of fancy stuff.

image

The callback function looked something like the following:

private function clicked(event:MouseEvent):void

{

var button:button = event.target as Button;

trace(button.label);

}

The problem with this was that if the user started clicking on buttons really fast a null pointer exception would occur, because the “button” instance was null. After debugging this I realized that the button was null because for a few cases when the button was clicked the event.target was a UITextField, what?

That is when a stumbled onto some more event documentation currently located at http://livedocs.adobe.com/flex/3/html/help.html?content=16_Event_handling_5.html:

The target property

The target property holds a reference to the object that is the target of the event. In some cases, this is straightforward, such as when a microphone becomes active, the target of the event object is the Microphone object. If the target is on the display list, however, the display list hierarchy must be taken into account. For example, if a user inputs a mouse click on a point that includes overlapping display list objects, Flash Player and AIR always choose the object that is farthest away from the Stage as the event target.

For complex SWF files, especially those in which buttons are routinely decorated with smaller child objects, the target property may not be used frequently because it will often point to a button's child object instead of the button. In these situations, the common practice is to add event listeners to the button and use the currentTarget property because it points to the button, whereas the target property may point to a child of the button.

The currentTarget property

The currentTarget property contains a reference to the object that is currently processing the event object. Although it may seem odd not to know which node is currently processing the event object that you are examining, keep in mind that you can add a listener function to any display object in that event object's event flow, and the listener function can be placed in any location. Moreover, the same listener function can be added to different display objects. As a project increases in size and complexity, the currentTarget property becomes more and more useful.

Pay attention to the following statement in the section about the target property:

“…common practice is to add event listeners to the button and use the currentTarget property because it points to the button, whereas the target property may point to a child of the button.”

So after reading this I changed my code to use event.currentTarget from event.target, and it always returned the instance of the button that was clicked.

I also found another article (http://mysticnomad.wordpress.com/2008/03/21/difference-between-eventtarget-and-eventcurrenttarget-properties-in-an-event-object/) that clearly laid out the distinction between these two properties, and made the conclusion that “…you should always use event.currentTarget property instead of event.target.”

I agree.

3 comments:

Leo said...

Thanks for this! Helped me a great deal, currentTarget makes a lot more sense.

Chaitanya said...

Thanks!

shadow man said...

Thanks, that was what i need