ブラウザの JavaScript コードを呼び出す

(サンプル一覧を表示する)

FlashDevelop を使って、ブラウザの JavaScript コードを呼び出すテストをしてみました。

Flash 画面の中のテキストボックスにメッセージを書いて送信ボタンを押すと、
ブラウザの JavaScript の関数が呼び出されて、
HTML 内にメッセージが書き込まれます。

JavaScript 側から Flash のメソッドを呼び出すコードも入っています。
Flash 画面の下の、開始ボタンと停止ボタンを押してみてください。

2009/12/09 追記
Google Chrome で見ると動かないようになっていたので JavaScript 側のソースコードを修正しました。

Flash の実行画面
出力領域 (HTML)

Flash の画面上で送信ボタンを押すと、ここにテキストが追加されます。

停止を押すとわんこの動作を停止します。
もう一度動かす時は開始を押してください。

開始・停止ボタンは HTML タグで作っています。
ボタンが押された時、いったん JavaScript の
イベントハンドラのコードを呼び出し、
その中から Flash 内のメソッドを
呼び出しています。

ブラウザの JavaScript コードを呼び出す

ソースコード

Flash 側のソース
package 
{
	import flash.display.Bitmap;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.external.ExternalInterface;
	import flash.system.Security;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFieldType;
	
	/**
	 * ブラウザの JavaScript コードを呼び出すサンプル
	 * @author Hikipuro
	 */
	public class Main extends Sprite 
	{
		/**
		 * 埋め込み画像
		 */
		[Embed(source='../image/test001.png')]
		private var image1:Class;
		
		/**
		 * ビットマップ
		 */
		private var bitmap:Bitmap;
		
		/**
		 * テキスト入力欄
		 */
		private var textField:TextField;
		
		/**
         * ボタン
         */
        private var button1:SimpleButton;  
       
        /**
         * ボタンのラベル
         */
        private var buttonText1:TextField;
		
		/**
		 * 回転の角度
		 */
		private var angle:int = 0;
		
		/**
		 * 回転の半径
		 */
		private var r:int = 60;
		
		/**
		 * 停止フラグ
		 */
		private var stopFlag:Boolean = false;
		
		// ----------------------------------------------------------
		
		/**
		 * コンストラクタ
		 */
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		/**
		 * 初期化イベント
		 * @param	e
		 */
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			// ビットマップの準備
			bitmap = Bitmap(new image1);
			bitmap.cacheAsBitmap = true;
			bitmap.scaleX = 2.0;
			bitmap.scaleY = 2.0;
			addChild(bitmap);
			
			// テキスト入力欄の作成
			textField = new TextField();
			textField.x = 10;
			textField.y = 210;
			textField.type = TextFieldType.INPUT;
			textField.width = 230;
			textField.height = 20;
			textField.border = true;
			textField.borderColor = 0xcccccc;
			addChild(textField);
			
			// ボタンのラベルの作成
			buttonText1 = new TextField();
			buttonText1.autoSize = TextFieldAutoSize.CENTER;
			buttonText1.selectable = false;
			buttonText1.x = 278;
			buttonText1.y = 210;
			buttonText1.text = "送信";
			addChild(buttonText1);
			
			// ボタンの作成
			button1 = new SimpleButton();
			button1.upState = makeRoundRect(0xDDDDDD, 60, 20, 10);
			button1.overState = makeRoundRect(0xFFFFFF, 60, 20, 10);
			button1.downState = makeRoundRect(0xBBBBBB, 60, 20, 10);
			button1.hitTestState = button1.upState;
			button1.addEventListener(MouseEvent.MOUSE_DOWN, onButtonMouseDown);
			button1.x = 250;
			button1.y = 210;
			addChild(button1);
			
			// フレーム開始イベント登録
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			
			// JavaScript から呼び出し可能なメソッドを登録する
			try {
				Security.allowDomain("hiroshi.dnip.net");
				ExternalInterface.addCallback("flStart", flStart);
				ExternalInterface.addCallback("flStop", flStop);
			} catch (e:Error) {
				// Flash 開発環境でデバッグ時に、エラーが起きるのでスルーする
			}
		}
		
		/**
		 * ブラウザの、開始ボタンが押された時に呼ばれるメソッド
		 */
		public function flStart():void
		{
			stopFlag = false;
		}
		
		/**
		 * ブラウザの、停止ボタンが押された時に呼ばれるメソッド
		 */
		public function flStop():void
		{
			stopFlag = true;
		}
		
		/**
		 * フレーム開始イベント
		 * @param	event
		 */
		private function onEnterFrame(event:Event):void
		{
			// 停止フラグが立っている時は移動せずに終了
			if (stopFlag == true)
				return;
			
			angle += 2;
			bitmap.x = ((320 - bitmap.width) / 2)  + Math.cos(angle / 180 * Math.PI) * r;
			bitmap.y = ((240 - bitmap.height) / 2)  + Math.sin(angle / 180 * Math.PI) * r;
		}

		/**
		 * 送信ボタンが押された時のイベント
		 * @param	event
		 */
		private function onButtonMouseDown(event:MouseEvent):void
		{
			// 何も入力されてない時はそのまま終了
			if (textField.text == "")
				return;
			
			// JavaScript のコードを呼び出す
			try {
				ExternalInterface.call("jsSetText", textField.text);
			} catch (e:Error) {
				// Flash 開発環境でデバッグ時に、エラーが起きるのでスルーする
			}
			
			// 入力欄クリア
			textField.text = "";
		}
		
		/**
		 * 角丸の図形を描いたスプライトを作って返す
		 * @param	color	色
		 * @param	width	幅
		 * @param	height	高さ
		 * @param	round	角丸の大きさ
		 * @return	スプライト
		 */
		private function makeRoundRect(color:uint, width:int, height:int, round:int):Sprite
		{
			var s:Sprite = new Sprite();
			s.graphics.lineStyle(2);
			s.graphics.beginFill(color);
			s.graphics.drawRoundRect(0, 0, width, height, round);
			s.graphics.endFill();
			s.alpha = 0.3;
			return s;
		}
		
	}
	
}		

JavaScript 側のソース
<!-- SWF 表示領域。ここの内容は、 swfobject により書き換えられます。 -->
<div id="swf_container">
	<a href="http://www.adobe.com/go/getflashplayer">
		<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
	</a>
</div>

<!-- 文字列表示領域。ここに文字列が追加されます。 -->
<div id="outputArea" name="outputArea">
	<b>出力領域</b><br />
</div>

<!-- 開始・停止ボタン -->
<form>
	<input type="button" value="開始" onclick="flashStart();" />
	<input type="button" value="停止" onclick="flashStop();" />
</form>

<script type="text/javascript">
<!--
// Flash から呼ばれる関数
function jsSetText(message)
{
	var outputArea = document.getElementById("outputArea");
	outputArea.innerHTML += message + "<br />\n";
}

// 開始ボタンが押された時
function flashStart()
{
	var method = 'flStart';
	var obj = document.getElementById("swf01");
	if (obj && typeof obj[method] != "undefined") {
		obj[method]();
	}
}

// 停止ボタンが押された時
function flashStop()
{
	var method = 'flStop';
	var obj = document.getElementById("swf01");
	if (obj && typeof obj[method] != "undefined") {
		obj[method]();
	}
}
//-->
</script>

<script type="text/javascript">
<!--
// Flash を読み込む swfobject のコード
// allowScriptAccess パラメータを always にし、
// attributes の id と name を設定する。

var flashvars = {};
var params = {};
params.allowScriptAccess = "always";
var attributes = {};
attributes.id = "swf01";
attributes.name = "swf01";
swfobject.embedSWF("ExternalInterfaceTest.swf", "swf_container", "320", "240", "9.0.0", "expressInstall.swf", flashvars, params, attributes);
//-->
</script>		

Flash から送信される文字列は UTF-8 形式になっています。
IE と Firefox では、ページの文字コードが Shift-JIS になっていても
文字化けせずに表示されますが、Safari 等では文字化けすることがあるそうです。

Flash から文字列を受け取って、そのまま文字コード形式を変換せずに表示するページを作るときは、
ページの文字コードを UTF-8 にする方が良いと思います。

リンク