Adobe Flash非公式テクニカルノート マウスイベントMouseEvent.MOUSE_OVERとMouseEvent.ROLL_OVERの違い
マウスポインタがインスタンスにロールオーバーしたとき起こるマウスイベントには、InteractiveObject.mouseOver(定数MouseEvent.MOUSE_OVER)とInteractiveObject.rollOver(定数MouseEvent.ROLL_OVER)があります。しかし、その違いがわかりにくいようです。大まかにいえば、前者はイベントの細かい制御ができます。それに対して、後者はボタンやメニューなどのインターフェイスに手軽に使えます。本稿では、その具体的な内容を簡単にご説明します。 対となるロールアウトのマウスイベントは、それぞれInteractiveObject.mouseOut(定数MouseEvent.MOUSE_OUT)とInteractiveObject.rollOut(定数MouseEvent.ROLL_OUT)です。イベントの考え方はロールオーバーと基本的に変わりません。なお、マウスイベントの概要については、F-siteセミナーのレポート「イベントを制する者、ActionScript 3.0を制す」をお読みください。 01 イベントが起きるインスタンス けれど、単純なボタンのインターフェイスなどの場合、それでは困ることもあります。InteractiveObject.rollOutイベントは、リスナーを登録した親インスタンスがマウスイベントをまとめて受取り、子インスタンスひとつひとつを識別しません。 ふたつのイベントの違いを確かめるため、前出「イベントを制する者、ActionScript 3.0を制す」でご紹介したテスト用のスクリプトを試してみましょう(細かい内容はレポートをご参照ください)。タイムラインにふたつの子インスタンス(pen0_mcとpen1_mc)をもつ親MovieClipインスタンス(parent_mc)のフレームアクションとして書きます(図001)。以下にスクリプト001として再掲しました。親インスタンスのInteractiveObject.mouseOverとInteractiveObject.rollOverイベントに同じリスナー関数(xTrace())を登録しています。 スクリプト001■InteractiveObject.mouseOverとInteractiveObject.rollOverイベントの両方にリスナー関数を設定
図001■ふたつの子インスタンスが含まれた親MovieClipシンボルにフレームアクションを記述 リスナー関数(xTrace())は、引数に受取ったEventオブジェクトの3つのプロパティをtrace()関数で[出力]します(スクリプト001第4行目)。それぞれのプロパティの値は、下表001のとおりです。なお、インスタンスの参照はそのまま[出力]しても区別できませんので、DisplayObject.nameプロパティでインスタンス名を取出しています。 表001■Eventクラスのプロパティ
[ムービープレビュー]でひとつの子インスタンス(pen0_mc)にマウスポインタを重ねると、InteractiveObject.mouseOverとInteractiveObject.rollOverのふたつのイベントがともに生じます。しかし、イベントが起こったインスタンス(Event.targetプロパティの値)が異なることにご注目ください。前述のとおりInteractiveObject.rollOverイベントでは、子インスタンスへのマウスインタラクションも親インスタンス(parent_mc)が受取るのです。 rollOver parent_mc parent_mc ふたつの子インスタンスの重なった部分をとおって、もうひとつのインスタンス(pen1_mc)にマウスポインタを重ねると、その子インスタンスに対してInteractiveObject.mouseOverイベントが起こります(前掲図001)。けれど、InteractiveObject.rollOverイベントでは子インスタンスをまとめてひとつの親インスタンスとみなしますので、新たなイベントは発生しません。 mouseOver pen1_mc parent_mc InteractiveObject.mouseOverイベントを用いても、親インスタンスのDisplayObjectContainer.mouseChildrenプロパティをfalseに設定すればイベントは親インスタンスに生じるようになります[*1]。たとえば、前掲スクリプト001につぎの1ステートメントを加えれば、ふたつのイベントは同じように起こります。重なり合った子インスタンスの間でマウスポインタを動かしても、新たなイベントは生じません。
02 イベントのバブリング あるマウスイベントがバブリングするかどうかは、そのイベントオブジェクトのEvent.bubblesプロパティ(読取り専用)で確かめられます。MouseEventクラスの定数でプロパティ値を調べると、下表002のとおりMouseEvent.MOUSE_OVERがtrueでバブリングし、MouseEvent.ROLL_OVERはfalseなのでバブリングしません。実際、定数MouseEvent.MOUSE_OVERで登録したリスナー関数が、子インスタンスに起こったInteractiveObject.mouseOverイベントを扱えるのは、親インスタンスにイベントがバブリングするからです。 表002■ロールオーバーのマウスイベントとEvent.bubblesプロパティの値
バブリングするマウスイベントをうまく使った例は、ロールオーバーよりクリックの方が示しやすいです。そこでまた、前出「イベントを制する者、ActionScript 3.0を制す」からサンプルをひとつご紹介します(細かい内容はレポートをご参照ください)。クリックは、インスタンスのうえでマウスボタンを押して、同じインスタンスのうえで放したとき生じるイベントです。しかし、マウスボタンをインスタンスの外で放したときにも、何か処理を加えたい場合があります。 そこで、マウスイベントInteractiveObject.mouseDown(定数MouseEvent.MOUSE_DOWN)とInteractiveObject.mouseUp(定数MouseEvent.MOUSE_UP)を用います。どちらのマウスイベントもバブリングします。インスタンス上でマウスボタンを押してInteractiveObject.mouseDownイベントが起こったら、処理は始まります。続くマウスボタンを放すイベントInteractiveObject.mouseUpの発生が、インスタンス上か外かによって処理を分けるのがお題です。 以下にスクリプト002として再掲したフレームアクションを、ボタンにするMovieClipシンボルに書くと、まずインスタンス上でマウスボタンを押したとき"press"の文字が[出力]されます。つぎに、マウスボタンを放すのが同じインスタンス上なら"release"、外なら"releaseOutside"と[出力]されます。 スクリプト002■インスタンス領域外まで含めたマウスクリック操作を処理する
処理の流れを前出「イベントを制する者、ActionScript 3.0を制す」は、テニスのダブルスに例えて説明しています。前衛がボタンのインスタンス、後衛はステージ(Stageオブジェクト)です。
マウスボタンを放したのがインスタンス上か外かは、条件判定によることなく、バブリングするマウスイベントの流れにより切り分けています。つまり、インスタンス上でマウスボタンを放したとき、そのリスナー関数(xRelease()スクリプト002第7〜11行目)内のステートメント(第10行目)でStageオブジェクトのリスナー関数(xReleaseOutside())を除いているために、バブリングするマウスイベントはStageオブジェクトでは扱われなくなるのです[*2]。 このようにイベントのバブリングをうまく切り分けると、ActionScript 3.0に実装されていないインスタンス外でマウスボタンを放すというイベントもすっきりと加えられます。
03 ふたつのイベントの違い
ボタンのような単純なインターフェイスであれば、多くの場合子インスタンスでイベントを受取ることも、表示リストの親インスタンスにイベントを送ることも要らないでしょう。そういうときには、InteractiveObject.rollOverイベントでロールオーバーを扱うのが簡単です。 マウスイベントを細かく扱ったり、表示リスト内のイベントの流れを制御したいときには、InteractiveObject.mouseOverイベントが適しています。前掲スクリプト002のように、独自のマウスイベントを加えることもできます。ただし、イベントが発生するインスタンスやイベントのバブリングを正しく扱わないと、無駄な負荷が生じたり、予期しない結果に陥るので注意しなければなりません[*3]。
作成者: 野中文雄 Copyright © 2001-2011 Fumio Nonaka. All rights reserved. |
||||||||||||||||||||||||||||||||||||