- 2005-10-08 (土)
- ActionScript
前回エントリの続き。ActionScript 2.0 におけるターゲットパスの挙動について理解しておくべき挙動について説明してみています。予想してたよりずっと長文になっちゃってやや心苦しい感じ。これでもできるだけわかりやすく書いているつもりなんですけど...。ターゲットパスの挙動に振り回されてて、でも原因が判らなくてモンモンとしてる人の役に立てれば幸いです。
_parent の注意点
気をつけるべきは
this._parent と _parent が必ずしも同じになるとは限らない。
_parent はターゲットパス省略形の記述であること。
です。これも例で見ると判りやすくて、
例5) とあるムービークリップインスタンス child をステージ上に配置した状態でメインタイムラインに以下のコードを記述:
var hoge = "xxx"; child.onPress = function(){ trace(this._parent.hoge) //結果は xxx trace(_parent.hoge) //結果は undefined }
_parent.hoge は実はターゲットパス省略形の書き方なので、実際の参照先はスクリプトを書いている場所によって異なります。詳しくは前回エントリ「ターゲットパス記述を省略した場合の参照先について」を参照してください。この例の場合、スクリプトはメインタイムライン上に書かれているので _parent.hoge は実際には _root._parent.hoge ... つまりこのSWFを呼び出している親SWF側の hoge オブジェクトを参照する記述になります。余計な混乱を回避すべく、上位層への相対パス記述は常に this._parent を用いた方が無難かと思われます。
_root の注意点
※参照情報 - Flashユーザーガイド > 複数のタイムラインとレベルについて (\ja\Configuration\HelpPanel\Help\UsingFlash\00000121.html) より
_root は現在レベルのエイリアス参照です
どういう事かというと、メインタイムライン上で
var hoge = "xxx"; trace(_root.hoge); //結果は xxx trace(_level0.hoge); //結果は xxx
となるように、_root は常に現在のレベル(通常は _level0 )を指し示す暗黙参照(エイリアス)です。レベルの概念については上記ユーザーガイドを読んでもらうとして、次は「じゃあ、他のSWFのステージ上に読み込まれる場合はどうなるの?」について説明します。
例6)読み込まれるSWF(child.swf)と読み込む側SWF(parent.swf)それぞれのメインタイムライン上に以下のコードを記述:
-- child.swf ---- var hoge = "child"; trace(_root.hoge); -- parent.swf ---- var hoge = "parent"; loadMovieNum("child.swf",5);
この状態でまず child.swf を単独で実行すると trace 結果は期待通り "child" になります。一方、parent.swf 側ではレベル5 (_level5)に child.swf を読み込むようになっています。parent.swf を実行してみると今度の trace 結果もちゃんと "child" に。この時の _root.hoge は実際には _level5.hoge になっているわけです。ここで言いたいことは
他SWFに読み込まれる場合でも、異なるレベルに読み込まれる場合は _root 記述は問題を起こさない
ということ。じゃあ問題になるのはどういうときなの?というのが次の例です。
例7)読み込まれるSWF(child.swf)と読み込む側SWF(parent.swf)それぞれのメインタイムライン上に以下のコードを記述:
-- child.swf ---- var hoge = "child"; trace(_root.hoge); -- parent.swf ---- var hoge = "parent"; createEmptyMovieClip("inner_mc",1);
inner_mc.loadMovie("child.swf");
今度は parent.swf にてレベル5(_level5)に child.swf を読み込むのではなく、レベル0(_level0)上に新たなムービークリップインスタンスを作成し、その中に child.swf を読み込んでいます。つまり同一レベル上に child.swf を読み込んだ場合。どうなるかというと、trace 結果は "parent" になります。「_root は現在のレベルのエイリアス参照」という挙動に従い、この時の _root.hoge は実際には _level0.hoge になるからです。
以上、_root の注意点をまとめると、
他のSWFに読み込まれる可能性のあるSWF内にて _root.* 記述をしていると、読み込まれ方によっては正しく動作しなくなる。(例)createEmptyMovieClip() + loadMovie() 関数で _level0 上のムービークリップ内に読み込まれる場合
ということです。ActionScript2.0 にはこういった場合の回避方法として MovieClip._lockroot = true; というプロパティ設定がありますが、これはあくまでも最終手段、やむをえない場合の対策として認識しておくのがベターかと思います。
結論
以上、かなり長くなってしまいましたが結論としては
余計な心配をしたくないならば、すべての参照においてきちんと this で始まるターゲットパス記述をすべし(this.hoge や this._parent.hoge)
という事なのかなぁ。といってもこれをやるとソースが見難くなるので、あんまり好きでは無いんですが。うーん。
- Newer: コールバック関数内で親クラスのメソッドを実行する方法
- Older: ターゲットパスの挙動をきちんと整理してみる