Wednesday, February 17, 2010

AS3: Preventing a parent from getting a Child's mouse clicks

If you have code that is like this:

var parent_sprite:Sprite = new Sprite();

parent_sprite.addEventListener(MouseEvent.CLICK,
handle_mouse_click);
addChild(parent_sprite);

function handle_mouse_click(event:MouseEvent):void {
parent_sprite.removeEventListener(MouseEvent.CLICK,
handle_mouse_click);
var child_sprite:Sprite = new Sprite();
draw_button_using_child_sprite(); // Some func to
// draw a button
child_sprite.addEventListener(MouseEvent.CLICK,
handle_button_click);

parent_sprite.addChild(child_sprite);
}

function handle_button_click(event:MouseEvent):void {
do_my_stuff();
parent_sprite.removeChild(child_sprite);
parent_sprite.addEventListener(MouseEvent.CLICK,
handle_mouse_click);
}

Now one would expect that on clicking on the parent_sprite, the child_sprite would appear. On click on the child_sprite, some stuff would get done and then the child_sprite is removed and the parent_sprite would be the only one on screen.

What I experienced is, that the child_sprite reappeared on the screen. This was because the parent was registering a click as soon as the event for the parent was registered again in handle_button_click() and was doing a addChild(child_sprite). The reason for this is that AS3 has a concept of "bubbling" where a event is passed down to the parent once the child is done with it and it will continue down the chain to the stage.

The solution to this is to use stopPropagation() or stopImmediatePropagation(). stopPropagation() will only prevent parent from receiving the events. While stopImmediatePropagation will prevent everyone listening for the event in the chain from receiving it.

So the code would be:

var parent_sprite:Sprite = new Sprite();
addChild(parent_sprite);
parent_sprite.addEventListener(MouseEvent.CLICK,
handle_mouse_click);


function handle_mouse_click(event:MouseEvent):void {
parent_sprite.removeEventListener(MouseEvent.CLICK,
handle_mouse_click);

var child_sprite:Sprite = new Sprite();
draw_button_using_child_sprite(); // Some func
// to draw a button

child_sprite.addEventListener(MouseEvent.CLICK,
handle_button_click);


parent_sprite.addChild(child_sprite);
}

function handle_button_click(event:MouseEvent):void {
do_my_stuff();
parent_sprite.removeChild(child_sprite);
parent_sprite.addEventListener(MouseEvent.CLICK,
handle_mouse_click);

event.stopPropagation(); // Prevent parent from
// receiving event

}

Got the information for this from:
http://www.kirupa.com/forum/showpost.php?p=1948149&postcount=202

1 comment: