ExternalInterface.addcallback
ExternalInterface.addcallbackはFlash(swf)とHTML(JavaScript)を連携させる場合に使う。
JavaScriptから任意のタイミングでswfの関数を呼び出し、引数を得ることができる。
今回はhtml上のボタンから、JavaScript上の関数(as3sendToActionScript)を実行し、ActionScript上の関数を実行するものを作ってみた。
ボタンをクリックすると、Flash内の赤丸が移動する。
以下、実行例とダウンロードファイル一式
↓AS2版
//JSと交信する機能を読み込みます。
import flash.external.ExternalInterface;
//テキストエリアをつくります。
_root.createTextField("return_txt", 0, 0, 0, 300, 20);
return_txt.text += "JSからの命令を待っています。";
//円を描きます。
_root.createEmptyMovieClip("_mc",1);
_mc.lineStyle (50, 0xFF0000, 100);
_mc.moveTo (Stage.width/2, Stage.height/2);
_mc.lineTo (Stage.width/2, Stage.height/2+1);
/**
* JSからの命令はExternalInterface.addCallbackを経由して、
* 関数に引き渡されます。
*/
function addCallback(myValue:Number):Void {
var houkou:Array = ["左", "下", "上", "右"];
return_txt.text = "JSからの命令を受け取れました。"+houkou[myValue]+"に移動します。";
switch (myValue) {
case 0 :
_mc._x -= 5;
break;
case 1 :
_mc._y += 5;
break;
case 2 :
_mc._y -= 5;
break;
case 3 :
_mc._x += 5;
break;
}
}
//JSから受け取る準備をします。
ExternalInterface.addCallback("JS2AS", null,addCallback);
↓AS3版
package
{
/**
* ...
* @author umhr
*/
import flash.display.Shape;
import flash.display.Sprite;
import flash.external.ExternalInterface;
import flash.text.TextField;
public class Main extends Sprite
{
private var tfStatus:TextField = new TextField();
private var shape:Shape = new Shape();
public function Main():void {
//円を描きます。
shape.graphics.beginFill (0xFF0000, 1.0);
shape.graphics.drawCircle ( stage.stageWidth/2, stage.stageHeight/2 , 25);
stage.addChild(shape);
//テキストエリアをつくります。
tfStatus.width = 300;
tfStatus.text = "JSからの命令を待っています。";
addChild(tfStatus);
//JSから受け取る準備をします。
ExternalInterface.addCallback("JS2AS", addCallback);
}
/**
* JSからの命令はExternalInterface.addCallbackを経由して、
* 関数に引き渡されます。
*/
private function addCallback(myValue:int):void {
var houkou:Array = ["左", "下", "上", "右"];
tfStatus.text = "JSからの命令を受け取れました。" + houkou[myValue] + "に移動します。";
switch (myValue) {
case 0:
shape.x -= 5;
break;
case 1:
shape.y += 5;
break;
case 2:
shape.y -= 5;
break;
case 3:
shape.x += 5;
break;
}
}
}
}
↓html側のJavaScript
//AS3版のボタンを押した時に実行される関数
function as3sendToActionScript(num){
swfName("externalas3addcallback").JS2AS(num);
}
//AS2版のボタンを押した時に実行される関数
function as2sendToActionScript(num){
swfName("externalas2addcallback").JS2AS(num);
}
//ブラウザに対応した呼び出し方のための関数
function swfName(str) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[str];
}else {
return document[str];
}
}
ファイル一式 >>ダウンロード
【関連】
ExternalInterface.call(ASからJSを呼び出す)
http://www.mztm.jp/2009/05/24/externalinterfacecall/
【参考】ExternalInterface – ActionScript 3.0 言語およびコンポーネントリファレンス
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/external/ExternalInterface.html
swf内だけで完結する動作ではないので、どうしてもブラウザ側との相性の問題がでてくる。
ハマり報告がいくつかあるの確認すること。
ExternalInterfaceにハマる
http://www.ironhearts.com/diary/archives/001473.html
Flashが何故かうまく動かない時に疑うべき8つの要素
http://blog.flair4.jp/2009/03/flash-debug-pattern.html
ExternalInterfaceでActionScriptの関数呼び出し失敗への対策
http://blog.katsuma.tv/2008/02/externalinterface_error.html
> 「*external*」な名前にしておかないとIEでコケる場合があります。
> ExternalInterface.addCallbackが確実に完了してから呼び出す
【余談】
作っている段階でFlashCS3でパブリッシュして意図通りに動いたものが、FlashCS4でパブリッシュすると動かない、ということがあった。これは、コードの記述ミスだった。
誤:private var wasSuccessful:* = ExternalInterface.addCallback(”JS2AS”, fn);
正:ExternalInterface.addCallback(”JS2AS”, fn);
返り値のないメソッドに対して、返り値を取得しようとしていた。
CS3ではaddCallbackは動き返り値に関しては無視されるが、CS4ではエラーログも出さずに単に動かない、という現象になった。
CS3とCS4でミスの許容度が異なるようだ。





