アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

【Flex】FlexからJavascriptを実行してみる

こんにちは、橋本です。

今日は、FlexからJavascript関数へアクセスする方法についてお話したいと思います。

FlexからJavascriptへアクセスするためには、ExternalInterface APIを使います。

使い方は非常に簡単です。call()メソッドを使ってラッパーのJavascriptを呼び出すだけです。
Javascriptの関数に引数を渡したり、Javascript側から戻り値を受け取ることも可能です。

簡単なコードを書いて、実際に使ってみましょう。

Flexコード


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600">
	<mx:Script>
		<![CDATA[
			import flash.external.*;
			
			import mx.controls.Alert;
			
			public function setWrapperTitle(title:String):void
			{
				var ret:String;
				
				if (ExternalInterface.available)
				{
					ret = ExternalInterface.call("setTitle",title);
				}
				else
				{
					ret = "Fault";
				}
				
				Alert.show(ret);
			}
	
			protected function execBtn_clickHandler(event:MouseEvent):void
			{
				this.setWrapperTitle(this.titleInput.text);
			}
		]]>
	</mx:Script>
	<mx:Panel id="hoge"
			  width="280"
			  height="150"
			  x="{this.width / 2 - hoge.width / 2}"
			  y="{this.height / 2 - hoge.height / 2}"
			  title="タイトル変更"
			  >
		<mx:Form>
			<mx:FormItem label="タイトル:">
				<mx:TextInput id="titleInput"/>
			</mx:FormItem>
		</mx:Form>
		<mx:ControlBar width="100">
			<mx:Spacer width="100%"/>
			<mx:Button id="execBtn"
					   label="変更"
					   click="execBtn_clickHandler(event)"
					   />
		</mx:ControlBar>
	</mx:Panel>
	
</mx:Application>


ラッパーにScriptタグを追加して、Flexで呼び出す関数を設定します。



<script language="JavaScript" type="text/javascript">
	function setTitle(title)
	{
		window.document.title = title;
		
		return "success";
	}
</script>


実行結果がこちらです。







また、オブジェクトや配列をそのまま渡すことも可能です。
先程のソースを少し修正します。



<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600">
	<mx:Script>
		<![CDATA[
			import flash.external.*;
			
			import mx.controls.Alert;
			
			public function setWrapperTitle(obj:Object):void
			{
				var ret:String;
				
				if (ExternalInterface.available)
				{
					ret = ExternalInterface.call("setTitle",obj);
				}
				else
				{
					ret = "Fault";
				}
				
				Alert.show(ret);
			}
	
			protected function execBtn_clickHandler(event:MouseEvent):void
			{
				var obj:Object = 
				{
					title1: this.titleInput1.text,
					title2: this.titleInput2.text
				};
				
				this.setWrapperTitle(obj);
			}
		]]>
	</mx:Script>
	<mx:Panel id="hoge"
			  width="300"
			  height="180"
			  x="{this.width / 2 - hoge.width / 2}"
			  y="{this.height / 2 - hoge.height / 2}"
			  title="タイトル変更"
			  >
		<mx:Form>
			<mx:FormItem label="タイトル1:">
				<mx:TextInput id="titleInput1"/>
			</mx:FormItem>
			<mx:FormItem label="タイトル2:">
				<mx:TextInput id="titleInput2"/>
			</mx:FormItem>
		</mx:Form>
		<mx:ControlBar width="100">
			<mx:Spacer width="100%"/>
			<mx:Button id="execBtn"
					   label="変更"
					   click="execBtn_clickHandler(event)"
					   />
		</mx:ControlBar>
	</mx:Panel>
	
</mx:Application>


javascriptの方も、オブジェクトを受け取るように変更


<script language="JavaScript" type="text/javascript">
	function setTitle(obj)
	{
		window.document.title = obj.title1 + obj.title2;
		
		return "success";
	}
</script>


実行結果







また、無名関数をFlex内で直接記述して実行することも可能です。

さきほどのコードを、無名関数を使うように変更します。


	public function setWrapperTitle(obj:Object):void
	{
		var ret:String;
				
		if (ExternalInterface.available)
		{
			ret = ExternalInterface.call(
				"function(obj)" +
				"{" +
					"window.document.title = obj.title1 + obj.title2;" +
					"return 'success';" +
				"}"
			, obj);
		}
		else
		{
			ret = "Fault";
		}
		
		Alert.show(ret);
	}
	


実行結果は先程の例と同様になります。

無名関数を使うことで、適用の幅が広がると思います。
非常に簡単ですので、試してみてください。