flash propagation_intervention
Interrupting event propagation
It is possible to interrupt the propagation of an event from any node. What is the interest in interrupting an event during its capture phase or bubbling phase?
In certain cases we nay need to disable everything in an application, for example the selection of interactive elements in an application or a game.
Two methods defined in the class flash.events.Event allow us to intervene in the propagation.
eventObject.stopPropagation() eventObject.stopImmediatePropagation()
These two methods are practically identical but differ slightly, we’ll spend some time on this now.
Let’s imagine we would like to disable all the buttons in our previous example. In the following example we’re going to interrupt the propagation of a MouseEvent.CLICK event during the capture phase. By stopping it’s propagation at the container level, we’re going to prevent it from reaching the target object. So the target phase will never be reached.
In order to interrupt the MouseEvent.CLICK event before it arrives at the target object we listen to the MouseEvent.CLICK event during the capture phase in the windowContainer container:
// number of windows var lng:int = 12; // create the container var windowContainer:Sprite = new Sprite(); // add to the display list addChild ( windowsContainer ); var myWindow:Window; for (var i:int = 0; i< lng; i++ ) { myWindow = new Window(); // register each instance for the target phase myWindow.addEventListener ( MouseEvent.CLICK, clickWindow ); myWindow.x = 7 + Math.round ( i % 3 ) * ( myWindow.width + 10 ); myWindow.y = 7 + Math.floor ( i / 3 ) * ( myWindow.height + 10 ); windowContainer.addChild ( myWindow ); } // register the MouseEvent.CLICK event of the container for the capture phase windowContainer.addEventListener ( MouseEvent.CLICK, clickWindow, true ); function clickWindow ( pEvt:Event ):void { // the instance of the window clicked is deleted from the display windowContainer.removeChild ( DisplayObject ( pEvt.target ) ); // unsubscribe the MouseEvent.CLICK from the clickWindow function pEvt.target.removeEventListener ( MouseEvent.CLICK, clickWindow ); } function captureClick ( pEvt:MouseEvent ):void { // display : Event capture : click trace("Event capture : " + pEvt.type ); }
We note that the captureClick function is executed on each button click.
To stop the propagation, we call the stopPropagation method on the broadcasting object:
function captureClick ( pEvt:MouseEvent ):void { // output : Target object : [object Window] trace( "Target object : " + pEvt.target ); // output : Notified object : [object Sprite] trace( "Notified object : " + pEvt.currentTarget ); // output : Event capture : click trace("Event capture : " + pEvt.type ); pEvt.stopPropagation(); }
When the stopPropagation method is called, the event halts its propagation on the current node, so the clickWindow function is no longer called.
Thanks to the following code, the instances of the Window class are only deleted when the ALT button is pressed.
function captureClick ( pEvt:MouseEvent ):void { // output : Target object : [object Window] trace( "Target object : " + pEvt.target ); // output : Notified object : [object Sprite] trace( "Notified object : " + pEvt.currentTarget ); // output : Event capture : click trace("Event capture : " + pEvt.type ); if ( !pEvt.altKey ) pEvt.stopPropagation(); }
We come back to the properties of the MouseEvent class during the course of the next chapter called Interactivity.
Note, the stopPropagation method stops the propagation of the event to all subsequent nodes, but allows the execution of listeners registered on the current node. If we add another listener to the windowContainer, even though the propagation is halted, the listener is executed.
In order to demonstrate the stopImmediatePropagation method we will add a captureSubsequentClick method as another listener on the container:
// number of windows var lng:int = 12; // create the container var windowContainer:Sprite = new Sprite(); // add to the display list addChild ( windowContainer ); var myWindow:Window; for (var i:int = 0; i< lng; i++ ) { myWindow = new Window(); // register for the target phase for each instance myWindow.addEventListener ( MouseEvent.CLICK, clickWindow ); myWindow.x = 7 + Math.round ( i % 3 ) * ( myWindow.width + 10 ); myWindow.y = 7 + Math.floor ( i / 3 ) * ( myWindow.height + 10 ); windowContainer.addChild ( myWindow ); } // register for the MouseEvent.CLICK event of the container for the capture phase windowContainer.addEventListener ( MouseEvent.CLICK, captureClick, true ); // register for the MouseEvent.CLICK event of the container for the capture phase windowContainer.addEventListener ( MouseEvent.CLICK, captureSubsequentClick, true ); function clickWindow ( pEvt:Event ):void { // this instance of the window that was clicked is removed from the display windowContainer.removeChild ( DisplayObject ( pEvt.target ) ); // unsubscribe the clickWindow function from the MouseEvent.CLICK event pEvt.target.removeEventListener ( MouseEvent.CLICK, clickWindow ); } function captureClick ( pEvt:MouseEvent ):void { // output : Target object : [object Window] trace( "Target object : " + pEvt.target ); // output : Notified object : [object Sprite] trace( "Notified object : " + pEvt.currentTarget ); // output : Event capture: click trace("Event capture: " + pEvt.type ); if ( !pEvt.altKey ) pEvt.stopPropagation(); } function captureSubsequentClick( pEvt:MouseEvent ):void { trace("captureSubsequentClick listener function called"); }
In testing the previous code, we see that our function captureSubsequentClick is called even though the propagation of the event has been halted. However, when we call the stopImmediatePropagation method, the function captureSubsequentClick is no longer called:
function captureClick ( pEvt:MouseEvent ):void { // output : Target object : [object Window] trace( "Target object : " + pEvt.target ); // output : Notified object : [object Sprite] trace( "Notified object : " + pEvt.currentTarget ); // output : Event capture: click trace("Event capture: " + pEvt.type ); if ( !pEvt.altKey ) pEvt.stopImmediatePropagation(); }
Thanks to the stopPropagation and stopImmediatePropagation methods it is possible to interrupt the propagation of events, and we can precisely control their flow.
Worth remembering
- The stopPropagation method interrupts the propagation of an event but does not interfere with broadcasting it to any listeners on the current node
- The stopImmediatePropagation method interrupts the propagation of an event and interrupts it’s broadcast to any listeners on the current node
Mediabox Training Centre © 2000 - 2008 All rights reserved.
Adobe Authorized Training Centre. State convention under number 25 14 02167 14.
Mediabox : SARL au capital de 62.000€ - Activity number: 25 14 02167 14 - SIRET : 493 716 468 00027
MEDIABOX, 102 Avenue des Champs Elysées, 75008 PARIS - Tel. +33(0)2.31.91.96.89 - Fax. +33(0)2.72.68.56.42



