MithrilWorks

[AS] JavaScriptとの連携

 Flash Player 8以降で使用できるExternalInterfaceは、ActionScriptとFlashのコンテナの間での通信を実現するクラスである。今回はFlash Player 9以降を対象としたExternalInterfaceの使い方をまとめる。

ExternalInterfaceの概要

 前述の通り、ExternalInterfaceクラスは、ActionScriptとFlashのコンテナの間での通信を実現するクラスである。このクラスのcallメソッドおよびaddCallbackメソッドを用いることで通信を実現することができる。
 パッケージはflash.externalである。
function call(functionName: String ... arguments): *;
function addCallback(functionName: String, closure: Function): void;
 callメソッドは、JavaScriptで定義されている関数を呼ぶメソッドである。
 第1引数は関数名、第2引数以降はその関数に渡す引数である。詳しくはActionScriptからJavaScriptの関数を呼ぶで解説する。
 addCallbackメソッドは、JavaScriptから呼ばれる関数を定義するメソッドである。
 第1引数は関数名、第2引数は呼び出しの際に呼ばれるクロージャ関数を指定する。詳しくはJavaScriptからActionScriptの関数を呼ぶで解説する。

ActionScriptからJavaScriptの関数を呼ぶ

 ActionScriptからJavaScriptで定義された関数を呼び出すには、callメソッドを使う。
ActionScript
1
2
3
4
5
6
7
8
9
10
11
12
13
package {
  import flash.display.*;
  import flash.text.*;
  import flash.external.*;

  public class Main extends Sprite{
    public function Main() {
      var text: TextField = new TextField();
      text.text = String(ExternalInterface.call("test"));
      addChild(text);
    }
  }
}
 JavaScriptの関数は以下のとおりである。
JavaScript
1
2
3
function test() {
  return "JavaScript";
}
 これでJavaScriptの関数を呼ぶことができる。
 引数を渡す時は、第2引数以降に引数を指定する。ここで指定した引数は自動的にJavaScriptにおける適切な型に変換され渡される。戻り値は型を持たず、変数に代入する場合はキャストが必要である。
 また、戻り値としてJavaScriptの任意のオブジェクトを返すこともできる。この場合、キャストしてしまうと正常に動作しないため、型なしの変数として扱わなければならない。
ActionScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package {
  import flash.display.*;
  import flash.text.*;
  import flash.external.*;

  public class Main extends Sprite{
    public function Main() {
      var text: TextField = new TextField();
      var v: * = ExternalInterface.call("test");
      text.text = v.str;
      addChild(text);
    }
  }
}
 JavaScriptの関数は以下のとおりである。
JavaScript
1
2
3
4
5
6
7
var obj = new Object();
obj.str = "JavaScript";
obj.num = 100;

function test() {
  return obj;
}
 このようにActionScript 2.0と同様に型なしで戻り値を受け取る。受け取った戻り値は型なしの変数へ代入する。この変数のメンバへのアクセスは、JavaScriptで定義したメンバ変数名を用いて行う。

JavaScriptからActionScriptの関数を呼ぶ

 つぎに、JavaScriptからActionScriptの関数を呼ぶ方法を解説する。
 JavaScriptからActionScriptの関数を呼ぶには、addCallbackメソッドを使う。
ActionScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package {
  import flash.display.*;
  import flash.text.*;
  import flash.external.*;

  public class Main extends Sprite{

    private var text: TextField;

    public function Main() {
      text = new TextField();
      addChild(text);

      ExternalInterface.addCallback("test", callbackFunc);
    }

    private function callbackFunc(str: String): void {
      text.text = str;
    }
  }
}
 このようにすると、JavaScript側からはtestという関数名でクロージャ関数に指定した関数を呼びだすことができる。
 次に、JavaScriptでの記述方法を載せる。
JavaScript
1
2
3
4
5
6
7
8
9
function callASFunc(){
  getSWF("Externalswf").test("JavaScript");
}

function getSWF(id){
  if(navigator.appName.indexOf("Microsoft") != -1)
    return window[id];
  return document[id];
}
 埋め込まれているSWFオブジェクトを取得し、それに対しActionScriptで設定した関数名を呼ぶ。getSWFはSWFオブジェクトを取得する関数で、引数にはSWFのid(objectタグに指定する)を渡す。このIDは、一部のIEでは"External"という接頭辞を使わなければ動作しないことがある。
 また、JavaScriptから送った引数は自動的にActionScriptの型に変換される。上記例では文字列型に変換されている。

ExternalInterfaceを使用する際の注意

 最後にExternalInterfaceを使用する際の注意点を載せる。
 ExternalInterfaceで呼びだすJavaScript、あるいはJavaScriptから呼びだすActionScriptは同一ドメインでなければならない。つまり、JavaScriptとFlashのコンテナが同一ドメイン上にあることが前提となる。
 したがって、mixiアプリなどでFlashを用いる場合は、以下の設定をする必要がある。まず、HTMLファイルに以下を指定する。
<param name="allowScriptAccess" value="always" />
 さらに、ActionScript側で以下のように記述する。
flash.system.Security.allowDomain(sourceDomain);
 sourceDomainはFlashのコンテナのドメインを指定する。"*"を指定することで全てのドメインを対象とすることができる。
 以上がActionScriptとJavaScript間での簡単な通信方法である。しかし、ブラウザやFlashのバージョン、それらの組み合わせにより若干の挙動の差があるようなので、使用する際にはこの手順だけではうまく動作しない可能性もありうる。