Macromedia Flash非公式テクニカルノート Buttonのthis
Platform: All Buttonインスタンスに設定したスクリプトで、ターゲットパスとしてthisを使用すると、その記述場所や使用したイベントハンドラ(アクション/メソッド)によって異なった扱いがされます。簡単なサンプルスクリプトで、その内容を見てみましょう。 1. Buttonアクション(onイベントハンドラアクション内)のthis参照 まず、Buttonをクリックするまでは、アニメーションの再生をとめておく必要があります。そのためには、ムービークリップシンボルの第1フレームに、停止のフレームアクションを記述します。
つぎに、ムービークリップシンボルの第1フレームにButtonインスタンス配置したら、以下のButtonアクションを設定します。
「ムービープレビュー」を実行して、Buttonをクリックすると、アニメーションが開始します。Buttonアクションに記述した再生開始のステートメントthis.play()のthisは、スクリプトを記述したButtonインスタンス自身ではなく、配置されたアニメーション用のMovieClipを参照しているからです。MovieClipのイベントハンドラアクションの中では、thisがスクリプトを記述したMovieClipインスタンス自身を参照するのと異なる点です。 thisがスクリプトを設定したインスタンスを参照しないというのは、Buttonオブジェクトの場合にかぎった例外です。このような例外が定められたのは、Buttonがオブジェクトとして実装されていなかったFlash 5の仕様と互換性をもたせるためだと思われます(Flash 5では、Buttonはオブジェクトではなかったので参照のしようがなく、配置されたタイムライン(MovieClip)をその代わりにしたのでしょう)。 2. Buttonオブジェクトのイベントハンドラメソッドに記述したthis参照 イベントハンドラメソッドには、別途定義したfunction名(参照)を指定するか、名前のないfunction(「名前のない関数(匿名関数/関数リテラル)」参照)を直接代入します。ステートメントは、多くの場合フレームアクションに記述します。しかし、ボタンシンボルには、フレームアクションが設定できません(記述したフレームアクションは無視されます)。そこで、Buttonインスタンスを配置したムービークリップシンボルのフレームアクションに、スクリプトを追加することにします。 Buttonを指定するためには、インスタンス名が必要です。ここでは、my_btnとしました。Buttonインスタンスはムービークリップシンボルに配置されていますので、this.my_btnというターゲットパスの指定で参照できます。このインスタンスに対して、Button.onPressメソッドを定義することになります。
「ムービープレビュー」でButtonをクリックしても、MovieClipのアニメーションは再生されません。再生のためのステートメントthis.play()で、thisがMovieClipを参照していないからです。テスト用に追加してあるステートメントtrace(this)の出力結果を見ると、それが確認できます。なお、Buttonを内包したMovieClipのインスタンス名は、my_mcとしています。
Buttonオブジェクトのイベントハンドラメソッドに定義したfunction中では、thisは定義されたインスタンス自身を指すのです。イベントハンドラメソッドはFlash MXからの実装なので、Flash 5との互換性を考慮する必要がなく、thisはインスタンス自身を参照するという原則が貫かれたのでしょう。 3. Buttonのイベントハンドラメソッドで配置されたタイムラインを参照するには Buttonインスタンスmy_btnのひとつ上の階層ですから、プロパティ_parentを使えばよさそうに思えます。しかし、これだけでは正しく動作しません。
trace()ステートメントを使った確認用のステートメントを2行追加してあります。最初のステートメントは、thisと_parentの参照内容を出力します(配列アクセス[]を使用して2つの参照を格納したのは、2つのパスを1行で出力するためです)。2つ目のステートメントは、変数whereAmIの値を確認するものです。この変数は、イベントハンドラメソッドを定義する前のステートメントで値を設定しています。つまり、この変数はMovieClipインスタンスmy_mcのタイムライン変数です。「出力」ウィンドウの表示は、以下のようになります。
thisがButtonインスタンスmy_btnを参照することは、前に確認したとおりです。その後に続く_parentの参照パスは、_level0つまりメインのタイムライン(_root)になってしまっています。ですから、MovieClipのアニメーションが再生されなかったのです。 _parentがメインのタイムラインを参照した理由は、2つ目のtraceステートメントの結果に隠されています。変数whereAmIの値として、"In this MovieClip"が出力されました。つまり、このMovieClipのタイムライン変数が参照されて、その値が表示されたのです。traceアクションの引数に指定した変数whereAmIには、参照先を指定するターゲットパスがありません。ターゲットパスがないと、「デフォルト参照」[*1]としてスクリプトを記述したタイムラインが参照されるということです。
_parentはMovieClipのプロパティです。ですから、本来はターゲットパスを必要とします。ただ通常は、スクリプトを記述したタイムライン(MovieClip)の上位のMovieClipを参照するために使うので、ターゲットパスを指定しなくても問題はないのです。しかし、今回は事情が異なります。参照したいのは、functionを定義したButtonインスタンスが配置されているMovieClipです。ところが、ターゲットパスなしのデフォルトではスクリプトを記述したMovieClipが参照されます。そのデフォルトタイムラインmy_mcの_parentというと、MovieClipの配置されたメインのタイムライン(_level0)になってしまうのです。 Buttonインスタンスの配置されているタイムラインを参照したければ、_parentプロパティのターゲットパスを明示的に指定しなければなりません。つまり、以下のように修正すればよいのです[*2]。
_parentプロパティのターゲットパスとして、thisを指定しました。thisは、イベントハンドラメソッドに定義したfunction内では、メソッドを設定したButtonインスタンスを参照しました。ターゲットパスが指定されたので、_parentプロパティはその上位のタイムライン、つまりButtonインスタンスmy_btnを包含するMovieClipのmy_mcを参照することになるのです。
_____ 作成者: 野中文雄 Copyright © 2001-2006 Fumio Nonaka. All rights reserved. |
|||||||||||||