Flex与JavaScript的相互通信(真情贡献)

近期正在做有关Flex的项目,由于需要将Flex的应用嵌入到HTML中,实现Flex与JavaScript的相互通信。本人在做这项工作的时候也浏览了一些贴子,发现国人的帖子太过简单,让刚刚接手的人总有一种摸不着头脑的感觉。在众多的网站和帖子中有一英文的网站对Flex与Javascript之间的相互通信的问题进行了详细的介绍,名曰:Switch On the Code,写的委实不错,现借他示例对该问题做一个了结。

进入正题。。。

在Flex与JavaScript相互通信的过程中,使用了一个非常重要的类——ExternalInterface 通过 ExternalInterface 类,您可以在 Flash 运行时中使用 HTML 页面中的 JavaScript 调用 ActionScript 函数。ActionScript 函数可以返回一个值,JavaScript 会立即接收它作为该调用的返回值。它有两个非常重要且比较常用的方法:

 

  •   ExternalInterface.call (functionName:String, ...parameters):
  • ExternalInterface.addCallback (functionName:String, closure:Function);

其中,第一个方法是为Flex调用JS做准备的,第二个方法是为JS调用Flex方法准备的他们的具体用法将在下面的小例子中得以体现。

在这个小示例中要实现的是:1,将Flex中有关人的信息:姓名、年龄、性别传递到HTML页面中。2,新创建一个人,并将其信息传到Flex中显示。

如果你正在用FLEX Builder(我用的时FlashBuilder 4),那么你需要先创建一flex应用,我为它起了个名字叫“FlexAndJavascript".接下来你将看到下面最简单的应用: 

 

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   width="462" height="328">
	<fx:Declarations>
		<!-- 将非可视元素(例如服务、值对象)放在此处 -->
	</fx:Declarations>
</s:Application>

 

 然后需要加入一个DataGrid用以显示人的信息,其中包括姓名、年龄和性别,如下布局:

 

<fx:Script>
		<![CDATA[
			import flash.external.*;
			
			import mx.collections.ArrayCollection;
			
			public function initDG():void
			{
				var people:Array = new Array();
				people.push({Name: "Charlie", Age: "23", Sex: "Male"});
				people.push({Name: "Brandon", Age: "23", Sex: "Male"});
				people.push({Name: "Mike", Age: "23", Sex: "Male"});
				people.push({Name: "Caroline", Age: "23", Sex: "Female"});
				var peopleCollection:ArrayCollection = new ArrayCollection(people);
				dgPeople.dataProvider = peopleCollection;
				dgPeople.selectedIndex = 0;
			}
			
		]]>
	</fx:Script>
<s:Panel id="pnlMain" x="0" y="0" width="462" height="328"
			 title="Simple Javascript Interaction">
		<s:DataGrid id="dgPeople" x="10" y="10" width="422" height="229" initialize="initDG()">
			<s:columns>
				<s:ArrayList>
					<s:GridColumn dataField="Name" headerText="Name"></s:GridColumn>
					<s:GridColumn dataField="Age" headerText="Age"></s:GridColumn>
					<s:GridColumn dataField="Sex" headerText="Sex"></s:GridColumn>
				</s:ArrayList>
			</s:columns>
		</s:DataGrid>
		<s:Button id="butJSDisplay" x="10" y="256" label="JavaScript Display"
				  click="jsDisplayPerson()"/>
		<s:Label id="lblMessage" x="149" y="260"/>
	</s:Panel>  

 

  initialize="initDG()"方法是用来初始化DataGrid数据的,将会在DataGrid中显示出ArrayCollection中的数据。下面我要

实现的是,当我点击一个按钮式我要将Datagrid当前行的数据传到HTML中。好看代码:

 

public function jsDisplayPerson():void
			{
				if (ExternalInterface.available) {
					ExternalInterface.call("displayPerson", dgPeople.selectedItem); 
					lblMessage.text = "Data Sent!";
				} else
					lblMessage.text = "Error sending data!";
			}

 在这里我们用了粗体显示的方法,这个方法就是用来通过调用JS中的方法displayPerson()将Flex中的数据传到HTML中。下面看JS中的displayPerson()方法:

 

function displayPerson(person){
		if(person == null){ 
			alert("Please select a person, or maybe I screwed up.");
		}
		else{
			document.getElementById('nameDisplay').innerHTML = person.Name;
			document.getElementById('ageDisplay').innerHTML = person.Age;
			document.getElementById('sexDisplay').innerHTML = person.Sex;
		}
	}

 也许你将困惑nameDisplay之类是什么东西,贴出来你就明白了,这里是要让person的Name,Age和Sex传到text中显示出来:贴代码:

 

<table width="100%" style="border-spacing:5px;">
	          <tr>
	            <td>Name:</td>
	            <td id="nameDisplay" style="width:150px;">&nbsp;</td>
	          </tr>
	          <tr>
	            <td>Age:</td>
	            <td id="ageDisplay" style="width:150px;">&nbsp;</td>
	          </tr>
	          <tr>
	            <td>Sex:</td>
	            <td id="sexDisplay" style="width:150px;">&nbsp;</td>
	          </tr>
	        </table>

 清晰了吗,好,接下来要做的就是要将swf文件嵌入到HTML中来搭成我们实验的环境。如何才能有效嵌入是个很大的问题,也是解决问题的关键,先看代码:

 

<div>	
		<object 
            classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"  
            id="newSWF"  
            codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">  
            <param name="movie" value="FlexAndJavaScript.swf" />  
            <param name="wmode" value="transparent">  
            <param name="quality" value="high" />  
            <param name="bgcolor" value="ffffff" />  
            <param name="allowScriptAccess" value="always" /> 
            <embed src="FlexAndJavaScript.swf" quality="high" bgcolor="ffffff"
                width="500"
                height="350"
                align="middle"
				name="newSWF"
                play="true"  
                wmode="transparent"  
                loop="false"  
                quality="high"  
                allowScriptAccess="sameDomain"  
                type="application/x-shockwave-flash"  
                pluginspage="http://www.adobe.com/go/getflashplayer">  
            </embed>  
        </object>
	   </div>

 这是一种嵌入的方式,粗体显示的是基本上必须要有的,而且命名属性值要搞的明白才行。<object>要有一个id,它要与<embed> 中的name相匹配。allowScriptAccess="sameDomain" 是用来处理不同域的情况。要注意的是SWF的路径要搞明白。

下面在说一下swf文件的问题,由于我们建立了flex工程,在bin—debug中生成的FlexAndJavaScript.swf是不能直接

拿来用的,需要先导出发行版的才可以拿来用——导出工程-发行版-生成bin-release,OK。

上面谈的是FLEX调用JS的方法,后面要说的时JS调用FLEX方法的情况,实现将HTML中提供的参数值传到FLEX的DataGrid中,不多说,看代码:

 

			public function addPerson(name:String, age:String,
									  sex:String):void
			{
				(dgPeople.dataProvider as ArrayCollection).addItem(
					{Name: name, Age: age, Sex: sex});
			}
			
			public function initApp():void
			{
				if (ExternalInterface.available)
					ExternalInterface.addCallback("addPerson", addPerson);  
			}

 addPerson是等着让JS调用的,在JS中调用后,传入参数,然后可以添加到DataGrid中。ExternalInterface.addCallback("addPerson", addPerson); 是一个非常重要的函数,他完成了一个比较艰巨的、

任务:完成注册功能,只有注册之后才能够顺利的Flex的函数进行调用,所以如此重要的方法现在Flex应用初始完成后就赶紧调用他吧,不调用就完蛋了,如下:

 

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   width="462" height="328" creationComplete="initApp();">

 flex端已经完成,在看HTML端是怎样的吧:

 

function getSWF(movieName){
		if (navigator.appName.indexOf("Microsoft") != -1){
		   return window[movieName]
	   }
	   else {
		   return document[movieName]
	   }
	}
	
	function addPerson()
	{
		var name = document.getElementById('txtName').value;
		var age = document.getElementById('txtAge').value;
		var sex = document.getElementById('selSex').value;
		getSWF('newSWF').addPerson(name, age, sex);
	}

 getSWF()方法的主要功能是对不同浏览器的支持,这个最好要,在addPerson()方法中完成了对Flex方法的调用——getSWF('newSWF').addPerson(name, age, sex);参数newSWF就是我们嵌入flash时定义的,就是在这里用的

 

 <table style="border-spacing:5px;" width="100%">
	          <tr>
	            <td style="border-style:none;padding:0px;">Name:</td>
	            <td style="border-style:none;padding:0px;"><input id="txtName" type="text" /></td>
	          </tr>
	          <tr>
	            <td style="border-style:none;padding:0px;">Age:</td>
	            <td style="border-style:none;padding:0px;"><input id="txtAge" type="text" /></td>
	          </tr>
	          <tr>
	            <td style="border-style:none;padding:0px;">Sex:</td>
	            <td style="border-style:none;padding:0px;"><select id="selSex" style="width:100px;"><option value="Male">Male</option><option value="Female">Female</option></select></td>
	          </tr>
	          <tr>
	            <td colspan="2" style="border-style:none;padding:0px;"><input type="button" id="butAddPerson" οnclick="addPerson()" value="Add Person" /></td>
	          </tr>
	        </table>

输入, 点一下按钮,OK了,完成。补充一下,对于不允许JS的浏览器也有办法:

 

<noscript>
            <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="462" height="328" id="FlexAndJavaScript">
            	<param name="src" value="FlexAndJavaScript.swf" />
                <param name="movie" value="FlexAndJavaScript.swf" />
                <param name="quality" value="high" />
                <param name="bgcolor" value="#ffffff" />
                <param name="allowScriptAccess" value="sameDomain" />
                <param name="allowFullScreen" value="true" />
                <!--[if !IE]>-->
                <object type="application/x-shockwave-flash" data="FlexAndJavaScript.swf" width="462" height="328">
                    <param name="quality" value="high" />
                    <param name="bgcolor" value="#ffffff" />
                    <param name="allowScriptAccess" value="sameDomain" />
                    <param name="allowFullScreen" value="true" />
                <!--<![endif]-->
                <!--[if gte IE 6]>-->
                    <p> 
                        Either scripts and active content are not permitted to run or Adobe Flash Player version
                        10.2.0 or greater is not installed.
                    </p>
                <!--<![endif]-->
                    <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>
                <!--[if !IE]>-->
                </object>
                <!--<![endif]-->
            </object>
    </noscript>     

 j加上就OK了。好完整的代码看一下:

FlexAndJava.mxml

 

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   width="462" height="328" creationComplete="initApp();">
	<fx:Declarations>
		<!-- 将非可视元素(例如服务、值对象)放在此处 -->
	</fx:Declarations>
	<fx:Script>
		<![CDATA[
			import flash.external.*;
			
			import mx.collections.ArrayCollection;
			
			public function initDG():void
			{
				var people:Array = new Array();
				people.push({Name: "Charlie", Age: "23", Sex: "Male"});
				people.push({Name: "Brandon", Age: "23", Sex: "Male"});
				people.push({Name: "Mike", Age: "23", Sex: "Male"});
				people.push({Name: "Caroline", Age: "23", Sex: "Female"});
				var peopleCollection:ArrayCollection = new ArrayCollection(people);
				dgPeople.dataProvider = peopleCollection;
				dgPeople.selectedIndex = 0;
			}
			
			public function addPerson(name:String, age:String,
									  sex:String):void
			{
				(dgPeople.dataProvider as ArrayCollection).addItem(
					{Name: name, Age: age, Sex: sex});
			}
			
			public function initApp():void
			{
				if (ExternalInterface.available)
					ExternalInterface.addCallback("addPerson", addPerson);  
			}
			
			public function jsDisplayPerson():void
			{
				if (ExternalInterface.available) {
					ExternalInterface.call("displayPerson", dgPeople.selectedItem); 
					lblMessage.text = "Data Sent!";
				} else
					lblMessage.text = "Error sending data!";
			}
			
			
		]]>
	</fx:Script>
	<s:Panel id="pnlMain" x="0" y="0" width="462" height="328"
			 title="Simple Javascript Interaction">
		<s:DataGrid id="dgPeople" x="10" y="10" width="422" height="229" initialize="initDG()">
			<s:columns>
				<s:ArrayList>
					<s:GridColumn dataField="Name" headerText="Name"></s:GridColumn>
					<s:GridColumn dataField="Age" headerText="Age"></s:GridColumn>
					<s:GridColumn dataField="Sex" headerText="Sex"></s:GridColumn>
				</s:ArrayList>
			</s:columns>
		</s:DataGrid>
		<s:Button id="butJSDisplay" x="10" y="256" label="JavaScript Display"
				  click="jsDisplayPerson()"/>
		<s:Label id="lblMessage" x="149" y="260"/>
	</s:Panel>  
	
</s:Application>

 FlexAndJava.html

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
	<head>
		<title>SWFObject 2 static publishing example page</title>
		<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
	
	</head>
	<body>
	 <center>
	  <div>	
		<object 
            classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"  
            id="newSWF"  
            codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">  
            <param name="movie" value="FlexAndJavaScript.swf" />  
            <param name="wmode" value="transparent">  
            <param name="quality" value="high" />  
            <param name="bgcolor" value="ffffff" />  
            <param name="allowScriptAccess" value="always" /> 
            <embed src="FlexAndJavaScript.swf" quality="high" bgcolor="ffffff"
                width="500"
                height="350"
                align="middle"
				name="newSWF"
                play="true"  
                wmode="transparent"  
                loop="false"  
                quality="high"  
                allowScriptAccess="sameDomain"  
                type="application/x-shockwave-flash"  
                pluginspage="http://www.adobe.com/go/getflashplayer">  
            </embed>  
        </object>
	   </div>
	  
	  <br>
	  <br>
	  <table class="sample">
	    <tr>
	      <td>
	        Data coming into Javascript
	      </td>
	    </tr>
	    <tr>
	      <td>
	        <table width="100%" style="border-spacing:5px;">
	          <tr>
	            <td>Name:</td>
	            <td id="nameDisplay" style="width:150px;">&nbsp;</td>
	          </tr>
	          <tr>
	            <td>Age:</td>
	            <td id="ageDisplay" style="width:150px;">&nbsp;</td>
	          </tr>
	          <tr>
	            <td>Sex:</td>
	            <td id="sexDisplay" style="width:150px;">&nbsp;</td>
	          </tr>
	        </table>
	      </td>
	    </tr>
	    <tr>  
	      <td>
	        Data sending from Javascript
	      </td>
	    </tr>
	    <tr>  
	      <td>
	        <table style="border-spacing:5px;" width="100%">
	          <tr>
	            <td style="border-style:none;padding:0px;">Name:</td>
	            <td style="border-style:none;padding:0px;"><input id="txtName" type="text" /></td>
	          </tr>
	          <tr>
	            <td style="border-style:none;padding:0px;">Age:</td>
	            <td style="border-style:none;padding:0px;"><input id="txtAge" type="text" /></td>
	          </tr>
	          <tr>
	            <td style="border-style:none;padding:0px;">Sex:</td>
	            <td style="border-style:none;padding:0px;"><select id="selSex" style="width:100px;"><option value="Male">Male</option><option value="Female">Female</option></select></td>
	          </tr>
	          <tr>
	            <td colspan="2" style="border-style:none;padding:0px;"><input type="button" id="butAddPerson" οnclick="addPerson()" value="Add Person" /></td>
	          </tr>
	        </table>
	      </td>
	    </tr>
	  </table>
	  </center>
	  
	<script>
	function getSWF(movieName){
		if (navigator.appName.indexOf("Microsoft") != -1){
		   return window[movieName]
	   }
	   else {
		   return document[movieName]
	   }
	}
	
	function addPerson()
	{
		var name = document.getElementById('txtName').value;
		var age = document.getElementById('txtAge').value;
		var sex = document.getElementById('selSex').value;
		getSWF('newSWF').addPerson(name, age, sex);
	}
	function displayPerson(person){
		if(person == null){ 
			alert("Please select a person, or maybe I screwed up.");
		}
		else{
			document.getElementById('nameDisplay').innerHTML = person.Name;
			document.getElementById('ageDisplay').innerHTML = person.Age;
			document.getElementById('sexDisplay').innerHTML = person.Sex;
		}
	}
	</script>
	<noscript>
            <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="462" height="328" id="FlexAndJavaScript">
            	<param name="src" value="FlexAndJavaScript.swf" />
                <param name="movie" value="FlexAndJavaScript.swf" />
                <param name="quality" value="high" />
                <param name="bgcolor" value="#ffffff" />
                <param name="allowScriptAccess" value="sameDomain" />
                <param name="allowFullScreen" value="true" />
                <!--[if !IE]>-->
                <object type="application/x-shockwave-flash" data="FlexAndJavaScript.swf" width="462" height="328">
                    <param name="quality" value="high" />
                    <param name="bgcolor" value="#ffffff" />
                    <param name="allowScriptAccess" value="sameDomain" />
                    <param name="allowFullScreen" value="true" />
                <!--<![endif]-->
                <!--[if gte IE 6]>-->
                    <p> 
                        Either scripts and active content are not permitted to run or Adobe Flash Player version
                        10.2.0 or greater is not installed.
                    </p>
                <!--<![endif]-->
                    <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>
                <!--[if !IE]>-->
                </object>
                <!--<![endif]-->
            </object>
    </noscript>     
	</body>
</html>

 有完整下载奥~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值