Arvind Mehta
Arvind Mehta

Reputation: 21

Differences between stopPropagation() and stopImmediatePropagation() in Flex

I am working on event handling in flex.
I need to stop event propagation of an event on a node.
I found no difference between stopPropagation() and stopImmediatePropagation().

Is there any difference between these functions?

<?xml version="1.0"?>
<s:Application     
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark"
    initialize="init(event);">

    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>

    <fx:Script>
        <![CDATA[
            import flash.events.Event;
            import flash.events.MouseEvent;         


            import mx.controls.Alert;

            public function init(e:Event):void {
                var object:Object
                p1.addEventListener(MouseEvent.MOUSE_DOWN, showAlert);
                tw1.addEventListener(MouseEvent.MOUSE_DOWN, showAlert);
                tw1.addEventListener(MouseEvent.MOUSE_UP, showAlert);
                btn.addEventListener(MouseEvent.MOUSE_DOWN, showAlert);
                btn.addEventListener(MouseEvent.MOUSE_UP, showAlert);               
            }

            private function showAlert(e:Event):void {                              
                trace("stopPropagation !\n" + "Current Target: " + e.currentTarget + "\n"+ "Target: " + e.target + "\n" +"Type: " + e.type);
                //e.stopImmediatePropagation();             
                e.stopPropagation();                                
            }

        ]]>
    </fx:Script>    
    <s:Panel id="p1" title="Stops Propagation">
        <mx:TitleWindow id="tw1" 
                        width="300" 
                        height="100" 
                        showCloseButton="true" 
                        title="Title Window 1">
            <s:Button id="btn" label="Click Me"/>
            <s:TextArea id="ta1"/>
        </mx:TitleWindow>
    </s:Panel>  
</s:Application>

Upvotes: 2

Views: 2761

Answers (1)

user770113
user770113

Reputation: 73

event.stopImmediatePropagation() - completely stops the event. No other listener will receive a call for that event.

event.stopPropagation() - prevents moving event to the next display list node but allow invoking listeners on the currentTarget object (if they exists).

See slightly modified your code:

<?xml version="1.0"?>
<s:Application
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark"
    initialize="init(event);">

    <fx:Script>
        <![CDATA[
            public function init(e:Event):void {
                var object:Object
                p1.addEventListener(MouseEvent.MOUSE_DOWN, showAlert);
                tw1.addEventListener(MouseEvent.MOUSE_DOWN, showAlert);
                btn.addEventListener(MouseEvent.MOUSE_DOWN, showAlert);
            }

            private function showAlert(e:Event):void {
                trace("Event: " + e.type + "; Phase: " + e.eventPhase +"; Target: " + e.target.name + "; Current Target: " + e.currentTarget.name);
            }
        ]]>
    </fx:Script>
    <s:Panel id="p1" title="Stops Propagation">
        <mx:TitleWindow id="tw1"
                        showCloseButton="true"
                        title="Title Window 1">
            <s:Button id="btn" label="Click Me"/>
            <s:TextArea id="ta1"/>
        </mx:TitleWindow>
    </s:Panel>
</s:Application>

Output:

Event: mouseDown; Phase: 2; Target: btn; Current Target: btn
Event: mouseDown; Phase: 3; Target: btn; Current Target: TitleWindow14
Event: mouseDown; Phase: 3; Target: btn; Current Target: Panel5

First you receive the event on Button in Targeting phase (eventPhase=2) and then on TitleWindow and Panel in Bubbling phase (eventPhase=3).

If you modify event listener like:

private function showAlert(e:Event):void {
                trace("Event: " + e.type + "; Phase: " + e.eventPhase +"; Target: " + e.target.name + "; Current Target: " + e.currentTarget.name);
                trace("stopPropagation()");
                e.stopPropagation();
            }

Output:

Event: mouseDown; Phase: 2; Target: btn; Current Target: btn
stopPropagation()

Or:

private function showAlert(e:Event):void {
                trace("Event: " + e.type + "; Phase: " + e.eventPhase +"; Target: " + e.target.name + "; Current Target: " + e.currentTarget.name);
                trace("stopImmediatePropagation()"); 
                e.stopImmediatePropagation();
            }

You will get the same result:

Event: mouseDown; Phase: 2; Target: btn; Current Target: btn
stopImmediatePropagation()

It is because stopPropagation() and stopImmediatePropagation() are prevent event to go into the next phase (Bubbling).

To see difference between these methods you need to have two event listeners on the button 'btn':

<?xml version="1.0"?>
<s:Application
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark"
    initialize="init(event);">

    <fx:Script>
        <![CDATA[
            public function init(e:Event):void {
                var object:Object
                p1.addEventListener(MouseEvent.MOUSE_DOWN, showAlert);
                tw1.addEventListener(MouseEvent.MOUSE_DOWN, showAlert);
                btn.addEventListener(MouseEvent.MOUSE_DOWN, showAlert);
                btn.addEventListener(MouseEvent.MOUSE_DOWN, showAlert2);
            }

            private function showAlert(e:Event):void {
                trace("showAlert(): Event: " + e.type + "; Phase: " + e.eventPhase +"; Target: " + e.target.name + "; Current Target: " + e.currentTarget.name);
                trace("showAlert(): stopPropagation()"); e.stopPropagation()                            // 1
                //trace("showAlert(): stopImmediatePropagation()"); e.stopImmediatePropagation();       // 2
            }

            private function showAlert2(e:Event):void {
                trace("showAlert2(): Event: " + e.type + "; Phase: " + e.eventPhase +"; Target: " + e.target.name + "; Current Target: " + e.currentTarget.name);
            }
        ]]>
    </fx:Script>
    <s:Panel id="p1" title="Stops Propagation">
        <mx:TitleWindow id="tw1"
                        showCloseButton="true"
                        title="Title Window 1">
            <s:Button id="btn" label="Click Me"/>
            <s:TextArea id="ta1"/>
        </mx:TitleWindow>
    </s:Panel>
</s:Application>

For stopPropagation() result is:

showAlert(): Event: mouseDown; Phase: 2; Target: btn; Current Target: btn
showAlert(): stopPropagation()
showAlert2(): Event: mouseDown; Phase: 2; Target: btn; Current Target: btn

For stopImmediatePropagation() result is:

showAlert(): Event: mouseDown; Phase: 2; Target: btn; Current Target: btn
showAlert(): stopImmediatePropagation()

As you can see stopPropagation() has allowed to receive mouseDown event for the second listener showAlert2().

At the same time stopImmediatePropagation() has prevented a call of showAlert2().

Upvotes: 4

Related Questions