[Flex3]イベントフェーズについて その1

イベントフェーズとは、イベントがトリガされた時にイベントリスナーが存在するかを確認する順番(段階)のことで、次の3段階構成になっています。

[ キャプチャ段階 ] → [ ターゲット段階 ] → [ バブリング段階 ]

 ●キャプチャ段階
  イベントが発行されたターゲットの祖先の表示リストを親側から順に検査し、リスナーが登録されているかを確認します。

 ●ターゲット段階
  イベントが発行されたターゲットのリスナーが呼び出されます。

 ●バブリング段階
  イベントが発行されたターゲットの祖先の表示リストをターゲット側から順に検査し、リスナーが登録されているかを確認します。

今回の その1 ではターゲット段階とバブリング段階に着目し、サンプルソースを通してイベントフェーズを確認していきます。

以下のサンプルソースは、入れ子構造の3つのVBox (外側から outerBox - middleBox - innerBox という id を付加) を用意し、ApplicationのcreationCompleteイベント処理で各々のVBoxにクリックイベントのリスナーを発行します。
サンプルソースを実行し何れかのVBoxをクリックすると、クリックイベントの処理として
 「 "リスナー処理対象VBoxのid":"処理連番"["イベントフェーズ段階"] 」
が右側にリスト表示されます。 わかりやすい様に文字色はVBoxの背景色と同色にセットしています。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" horizontalAlign="center" backgroundColor="#FFFFFF"
     creationComplete="onCreationComplete()" >
     
    <mx:Script>
        <![CDATA[
            import mx.controls.Label;
       
            private var counter:int = 1;
           
            private function onCreationComplete():void{   
                innerBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher);
                middleBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher);
                outerBox.addEventListener(MouseEvent.CLICK, onCatchDispatcher);
            }
           
            private function onCatchDispatcher(e:MouseEvent):void{
                var lbl:Label = new Label();
                var phase:String = getPhase(e.eventPhase);
                lbl.text = counter + " : " + e.currentTarget.id + " [" + phase + "]";
                setLabelColor(lbl, e.currentTarget.id);
                eventList.addChild(lbl);
                counter++;
            }
           
            private function getPhase(eventPhase:int):String{   
                var phase:String;
                //EventPhase 1=キャプチャ段階, 2=ターゲット段階, 3=バブリング段階
                switch(eventPhase){
                    case 1:
                        phase = "キャプチャ段階";
                        break;
                    case 2:
                        phase = "ターゲット段階";
                        break;
                    case 3:
                        phase = "バブリング段階";
                        break;
                }
               
                return phase;
            }
           
            private function setLabelColor(lbl:Label, targetBox:String):void{       
                if(targetBox == "innerBox"){
                    lbl.setStyle("color", "#CC0000");
                }else if(targetBox == "middleBox"){
                    lbl.setStyle("color", "#00CC00");
                }else if(targetBox == "outerBox"){
                    lbl.setStyle("color", "#0000CC");
                }
            }

        ]]>
    </mx:Script>
    <mx:HBox>
        <mx:VBox id="outerBox" minHeight="150" minWidth="150" horizontalAlign="center" verticalAlign="middle" backgroundColor="#0000CC">
            <mx:VBox id="middleBox" minHeight="100" minWidth="100" horizontalAlign="center" verticalAlign="middle" backgroundColor="#00CC00">
                <mx:VBox id="innerBox" minHeight="50" minWidth="50" horizontalAlign="center" verticalAlign="middle" backgroundColor="#CC0000" />
            </mx:VBox>
        </mx:VBox>
        <mx:VBox id="eventList" fontWeight="bold" />
    </mx:HBox>

</mx:Application>

 

【サンプルソースの実行】

① 一番内側の innerBox (赤色) を1回クリック
② 次に内側の middleBox (緑色) を1回クリック
③ 一番外側の outerBox (青色) を1回クリック

上記①~③の手順で実行した際の結果はこうなりました。

click_result.PNG

手順①では一番内側のコンポーネントがクリックされたことにより、ターゲット段階として innerBox がリスナーが実行されます。その後、親コンポーネントへの伝播が働くことにより、バブリング段階として middleBox・outerBox の順にリスナーが実行されます。

手順②では middleBox がクリックされたので ターゲット段階として middleBoxのリスナーが実行され、バブリング段階として 親コンポーネントである outerBox のリスナーが実行されます。

手順③では、一番外側のコンポーネントのouterBox がクリックされたので、バブリング段階対象のコンポーネントは存在せず、ターゲット段階の outerBox のリスナーのみ実行されます。

つまり、イベント発行したコンポーネントはターゲット段階としてリスナーを実行し、イベント発行したコンポーネントよりも親のコンポーネントはバブリング段階としてリスナーを実行しています。
考え方はシンプルですが、1つのアクション(イベント)で複数個所のリスナーを動かせる非常に強力なしくみですよね。

次回は、キャプチャ段階についてサンプルソースを見ながら確認したいと思います。

このブログについて

このブログは吉祥寺にあるブレインチャイルド株式会社の社員で投稿しています。
業務ではまってしまったことや発見したこと。
自分達で新たに学習してみようと思って勉強し始めたことなどを綴っています。
こんな社員が働いているブレインチャイルドに興味がわいててきたなら、是非お問い合わせください。
会社案内
求人案内
先輩のコメント