アクセシビリティ
デベロッパーリソース

目次

ActionScript 3.0のイベント処理について

イベントの伝達と段階

前の例でお気づきにならなかったかもしれませんが、boxをクリックして発生したイベントは、クリックしたオブジェクトだけでなく、多くの様々なオブジェクトにも影響を及ぼします。ActionScript 3.0のイベント処理における重要な新機能に、イベントの伝達のサポートがあります。イベントの伝達とは、1つのイベントが複数のオブジェクトに適用される転移現象です。これらの各オブジェクトは、イベントが発生したオブジェクトだけでなく、イベントも受け取ります。

ActionScript 2.0では、このようなイベントの伝達は行われませんでした。実際には、独自のイベントハンドラを持つ別のオブジェクト内で、特定のイベントハンドラが関連付けられているオブジェクトを扱うことさえできませんでした。例えば、ActionScript 2.0では、ボタンを含むウィンドウオブジェクトにonPressイベントハンドラを割り当てた場合、ボタンに割り当てられているonPress(または類似の)イベントハンドラは機能せず、イベントも受け取りません。ActionScript 3.0では、このような問題はなくなりました。イベントは、インスタンスやその親の間を伝達されるようになりました。

イベントの伝達には、3つの「段階」があります(図2を参照)。各段階は、イベントに関連する表示オブジェクトを介してFlashでイベントが処理される際の、イベントの経路または場所を表します。イベントの3つの段階は、キャプチャターゲットおよびバブリングです。

  • キャプチャ段階:イベントの発生元のターゲットオブジェクトの親オブジェクトを表します。伝達されるイベントは、最上位の親(stage)から始まり、発生元のターゲットに達するまで、表示オブジェクト階層を下っていきます。
  • ターゲット段階:ターゲット段階は、イベントがターゲットオブジェクトまたはイベントの発生元オブジェクトにある段階です。キャプチャ段階やバブリング段階とは異なり、この段階は、常に1つしかないターゲットオブジェクトに関連します。
  • バブリング段階:イベントが「バブルする」と、キャプチャ段階とは逆の経路をたどり、最上位の親(stage)に達するまで、ターゲットオブジェクトの親階層を上っていきます。

ただし、伝達されるイベントがすべて各段階を通過するわけではなく、すべてのイベントが伝達されるとも限りません。例えば、Stageオブジェクトがイベントを受け取った場合は、キャプチャ段階やバブリング段階が発生するために必要な、stageより下位のオブジェクトが存在しないので、ターゲット段階のみが発生します。

boxをクリックしたときに発生する3つのイベント段階の図

図2.boxをクリックしたときに発生する3つのイベント段階の図

注意:Flexの階層は、rootとboxのCanvasインスタンス(図では省略)との間にApplicationインスタンスが含まれているので、若干異なります。

イベントが各段階と段階にある各オブジェクトを通過していくとき、そのイベントのために追加されたリスナー関数がすべて呼び出されます。つまり、boxをクリックすると、イベントはboxだけでなく、stageにも渡されます。stageは、イベントを2回受け取ります。1回はキャプチャ段階で受け取り、もう1回はバブリング段階で受け取ります(図3を参照)。

boxをクリックしたときに発生するイベントの経路

図3.boxをクリックしたときに発生するイベントの経路

この例にリスナーを追加していくと、流れがより明確にわかるようになります。

例2:1つのboxに複数のリスナー

マウスで1回クリックすると、表示リスト階層内の多くのオブジェクトに伝達されていく様子を確認するため、影響を受ける各オブジェクトについてイベントを受け取るリスナーを追加します。この例ではイベントのすべての段階にリスナーを追加するので、addEventListenerの3番目のパラメータである、useCaptureパラメータを利用する必要があります。

addEventListeneruseCaptureパラメータを使用すると、リスナーがキャプチャ段階でリッスンするかどうかを指定できます。キャプチャ段階でリッスンしない場合は、ターゲット段階またはバブリング段階でイベントをリッスンします。ターゲット段階とバブリング段階でリッスンするため、リスナーにはデフォルト値falseが設定されています。true値を渡すと、キャプチャ段階でイベントをリッスンできます。すべての段階でイベントをリッスンするには、addEventListenerを2回使用します。1つはuseCaptureをfalseに設定するか、または省略し、もう1つはuseCaptureをtrueに設定します。

この例(図4を参照)では、stagerootboxに対してリスナーを追加します。stagerootに対しては、useCaptureパラメータを交互に使用するイベントリスナーを追加します。

boxをクリックすると、すべての段階で指定したすべてのリスナーにイベントが伝達される

図4.boxをクリックすると、すべての段階で指定したすべてのリスナーにイベントが伝達される

Flash CS3 Professional ActionScript 3.0プレビューの使用

  1. 例1のコードサンプルを開きます。
  2. フレーム1のタイムラインスクリプトを次のスクリプトに置き換えます。

    function boxClick(event:MouseEvent):void {
       trace("box click");
    }
    function rootClick(event:MouseEvent):void {
       trace("root click");
    }
    function stageClick(event:MouseEvent):void {
       trace("stage click");
    }
    
    box.addEventListener(MouseEvent.CLICK, boxClick);
    root.addEventListener(MouseEvent.CLICK, rootClick);
    root.addEventListener(MouseEvent.CLICK, rootClick, true);
    stage.addEventListener(MouseEvent.CLICK, stageClick);
    stage.addEventListener(MouseEvent.CLICK, stageClick, true);
    

Flex 2の使用

  1. 新しいFlex MXMLドキュメントを作成するか、例1のコードサンプルを編集します。
  2. 次のMXMLを使用します。

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                applicationComplete="initApp()">
       <mx:Script>
          <![CDATA[
             public function boxClick(event:MouseEvent):void {
                trace("box click");
             }
             public function rootClick(event:MouseEvent):void {
                trace("root click");
             }
             public function stageClick(event:MouseEvent):void {
                trace("stage click");
             }
    
             public function initApp():void {
                box.addEventListener(MouseEvent.CLICK, boxClick);
                root.addEventListener(MouseEvent.CLICK, rootClick);
                root.addEventListener(MouseEvent.CLICK, rootClick, true);
                stage.addEventListener(MouseEvent.CLICK, stageClick);
                stage.addEventListener(MouseEvent.CLICK, stageClick, true);
             }
          ]]>
       </mx:Script>
       
       <mx:Canvas id="box" width="200" height="200" backgroundColor="#800000">
       </mx:Canvas>
       
    </mx:Application>
    

注意:FlexではapplicationCompleteイベントを必ず使用して、Applicationスクリプト内のstageおよびrootにアクセスできるようにしてください。stagerootには、creationCompleteイベント内ではアクセスできません。

このムービーをテストし、いろいろな場所をクリックして結果を確認します。boxをクリックすると、以下の出力が表示されます。

stage click
root click
box click
root click
stage click

この出力は、stageオブジェクトとrootオブジェクトがイベントのキャプチャ段階とバブリング段階でそれぞれ1回ずつ、イベントを2回受け取ったことを示しています。一方、イベントのターゲットであるboxは、ターゲット段階で1回だけイベントを受け取っています。stage上のbox以外の場所をクリックしてみると、Flashを使用している場合は以下の出力が表示されます。

stage click

stageはFlashムービーの階層の最上位に位置するので、stageベースのイベントの段階は、ターゲット段階のみになります。

Flexで、stageをクリックすると、以下のような出力が表示されます。

stage click
root click
root click
stage click

これは、stageの領域全体を包含するグラデーション背景を含む中間のApplicationインスタンス(Application.application)の結果です。stageをクリックすることは、実際にはstage自体ではなく、リスナーを持たないこのインスタンスをクリックすることになります。中間のApplicationインスタンスが存在しない場合は、stageのリスナーのみが呼び出されます。

イベントの伝達はマウスイベントで最も頻繁に発生しますが、キーボードイベントなどの他のイベントでも発生します。イベントの伝達は、DisplayObjectContainerインスタンス内の追加イベントや削除イベントでも使用されます。この場合は、子オブジェクトがその表示リストに追加されるか、表示リストから削除されます。