- ベストアンサー
プルダウンメニューの移動
- プルダウンメニューの移動方法を教えてください。ムービークリップを使用して、ヘッドをドラッグしてメニューを動かしたいですが、うまくいきません。
- ムービークリップを使ったプルダウンメニューの移動方法を教えてください。ヘッドをドラッグするとメニューを動かしたいです。
- ムービークリップの中にヘッドがあり、ドラッグしてメニューを動かしたいです。しかし、うまくいきません。どのようにすればいいでしょうか?
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
this を使う時は、this の指す対象にご注意ください。 onClipEvent アクションで this を使った関数を定義していますが、このアクションと on アクションをインスタンス menu に設定した時は、this は menu を指します。従って、menu 全体をドラッグのヒット領域(マウスが反応する部分)とするドラッグの処理が実行されることになります。 onClipEvent と on アクションを、menu 内部の head インスタンス( menu の元になっているシンボルの中にあるインスタンス head )に設定すると、this はhead を指します。従って、この場合は head だけがドラッグのヒット領域になりますが、ドラッグした時に動くのも head だけです。 onClipEvent と on を設定した場所が違う場合は、少々ややこしくなります。 onClipEvent を menu に、on を head に設定した場合、関数を所有しているのは menu で、関数内で使われている this が指す対象、つまりドラッグの対象も menu になります。 しかし、on の中で使われている this が指しているのは head です。this.dragFunc として関数を呼ぶと、head が所有する dragFunc を呼ぶという意味になりますが、head では関数を何も定義していないのですから、関数は未定義と扱われ、処理は何も行われません。 ちなみに、head に設定されている on の中で menu.*** と書いた場合は、head の中( head の下の階層)にある menu ムービークリップのターゲットパスになります。今回のムービークリップの構成では menu の中に head があるはずので、この書き方では menu へ指示を出すことはできません。 結論として、どうすればいいかと言いますと。 head と menu は入れ子の状態、つまり親子階層になっています。head から見ると、menu は親階層にあたります。子階層から親階層を指定するために、_parent というアクションが用意されています。this ではなく、こちらを使ってみてはいかがでしょうか。 関数を定義する onClipEvent アクションと、関数を呼ぶ on アクションを、ともに、head に設定してください。 それから、onClipEvent 内で定義している関数で使われている this を、それぞれ _parent.startDrag(frame, -400, -300, 400, 300); _parent.stopDrag(); このように、_parent に変更してみてください。 head に onClipEvent を設定し、その中で関数を定義すると、各関数の所有者は head となり、head に設定した on の中で this.dragFunc としても関数は正常に呼び出されます。ドラッグのヒット領域は on が設定されている head だけですが、ドラッグの対象は head 自身ではなく、その親である menu になります。 関数が定義されているターゲットやドラッグの対象を最終的に正確に指すことさえできていれば、実は、書き方はどんな書き方でも動作はします。もっとも、正常に動くというだけの話であって、分かりやすい書き方・推奨される書き方であるかどうかは、また別の問題ですが。 例えば、ご質問文のにある通りのアクションで、関数を定義する onClipEvent を menu に、関数を呼ぶ on アクションを head に設定して、 on(press) { _root.menu.dragFunc(); } と、絶対パスで呼び出してもいいですし(ただし、シンボルの汎用性はなくなります)、あるいは on(press) { _parent.dragFunc(); } このように相対的に指定しても正常に呼び出されます。関数内の this は menu を指していますから、動くのは menu 全体ですが、ヒット領域になるのは、 on が設定されている head だけです。ただ、ドラッグの処理関数を所有しているのは menu ですので、head から関数を呼び出すには、menu までのターゲットパスの指定が必要です。 お使いの Flash が MX 以降であれば、MovieClip.on*** というイベントハンドラを利用して、クリックされた時に呼ぶ関数を予め定義しておくこともできます。 //headがクリックされたら、menuのドラッグを開始 _root.menu.head.onPress = function () { _root.menu.startDrag(); }; MovieClip.on*** を使う時も、ターゲットの指定に関するルールは同じです。this や _parent も利用できます。 どの書き方が一番いいかは状況によって変わります。 MovieClip.on*** を利用すると、1箇所にまとめて処理を書いておけるのでスクリプトの管理がしやすく、for 文と eval というアクションを利用して大量のインスタンスに対する指示を一気に定義するなどの荒技も可能です。 しかし、同じシンボルから複数のインスタンスを作り、全てのインスタンスで同じ処理をさせたい場合は、シンボルに設定した方が効率的です。 目的に合わせて、いろいろな書き方を試してみてください。 長くなってすみませんでした。 不明な点がありましたら補足してください。
お礼
ありがとうございます。 くわしいご説明で、大変よく分かりましたし、menu も動かすことができました。(flash は MX を使用しています。)