Friday, April 29, 2011

stopPropagation and stopImmediatePropagation

Generally, flex navigates its compelte display list, either upwards towards Application, in Bubbling or Target Phase
or downwards towards the immediate ancestor of the component/container which triggered the event in Capturing Phase.
However, we can stop this navigation or propagation using the following 2 methods of event:

1. stopPropagation: This is used to prevent the Event object from moving onto the next node, but allows the other event listeners (EVENT of same type, example another CLICK) on the current node to execute.
2. stopImmediatePropagation: This is used to prevent the Event object not only to move to next node, but it also does not allow the other event listeners (ONLY OF SAME TYPE, example another CLICK) on the current node to execute

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
click="clickHandler(event)" name="Application" initialize="initApp()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;

private function initApp():void {
myBtn1.addEventListener(MouseEvent.CLICK,anotherClickHandlerForBtn1);
myBtn1.addEventListener(MouseEvent.CLICK,clickHandler);
myBtn1.addEventListener(MouseEvent.ROLL_OUT,rollOutHandler);
myBtn2.addEventListener(MouseEvent.CLICK,anotherClickHandlerForBtn2);
myBtn2.addEventListener(MouseEvent.CLICK,clickHandler);
myBtn2.addEventListener(MouseEvent.ROLL_OUT,rollOutHandler);
}

/*
This will always execute for the buttons
irrespective of stopPropagation or stopImmediatePropagation
as this is a ROLL_OUT event (Event other then CLICK type for which
we are calling the stopPropagation or stopImmediatePropagation)
*/

private function rollOutHandler(event:MouseEvent):void {
Alert.show("Roll Out event for target("+event.target.name+")&"+
" currentTarget("+event.currentTarget.name+")");
}


/*
In this function, we are calling stopPropagation.
So, Flex tries to see if there are any other event other than CLICK on this object or CLICK event itself on parent container. And if there are, it does not execute them
However, if there are more than 1 CLICK handlers for this button itself, it executes all of them. And do not move to the next node in event flow.
*/

private function anotherClickHandlerForBtn1(event:MouseEvent):void {
Alert.show("This is first click handler and would also allow all the other" +
" click handlers of this 'Button 1' to execute (event.stopPropagation)" +
" and stop propagating to other nodes ",event.type);
event.stopPropagation();
}

/*
In this function, we are calling stopImmediatePropagation
So, As soon as this CLICK handler gets executed, Flex stops the event there itself and
no other events gets called (even if there is another CLICK handler, it won't execute)
And also, it does not moves on to the next node in event flow.
*/

private function anotherClickHandlerForBtn2(event:MouseEvent):void {
Alert.show("This will just allow the click handler of this 'Button 2' to execute" +
" and then would stop propagating the event to other click handlers on same node" +
" as well as other nodes (event.stopPropagation)",event.type);
event.stopImmediatePropagation()
}

private function clickHandler(event:MouseEvent):void {
Alert.show("Target object: "+event.target.name
+"\n"+
"Phase: "+getPhaseName(event.eventPhase)
+"\n"+
"Current Target object: "+event.currentTarget.name);
}

private function getPhaseName(phase:uint):String {
switch(phase) {
case 1:
return "CAPTURING PHASE";
case 2:
return "TARGET PHASE";
case 3:
return "BUBBLING PHASE";
}
return "";
}
]]>
</mx:Script>
<mx:Panel borderThickness="250" name="Panel" click="clickHandler(event)" width="700" height="300">
<mx:VBox backgroundColor="#EEEEEE" click="clickHandler(event)" name="VBox" height="200" width="600"
horizontalAlign="center" verticalAlign="middle">
<mx:Label text="Stops propagation to next node but does not stops other events on the same node to execute" />
<mx:Button id="myBtn1" name="Button 1" label="Button 1" />
<mx:Label text="Stops propagation to next node as well as stops other CLICK events on the same node to execute" />
<mx:Button id="myBtn2" name="Button 2" label="Button 2" />
</mx:VBox>
</mx:Panel>
</mx:Application>

No comments:

Post a Comment