JavaScript与ActionScript3交互问题总结

费好大的劲,终于搞定JavaScript和ActionScript3的交互问题了,呵呵,总结一下。在网上参考了好多资料,感觉http://www.coolcode.cn/show-291-1.html 和ActionScript3权威编程 最管用,在这里谢过了。

 

ActionScript3和外部的调用,一般采用ExternalInterface来调用,下面都是以这个接口的使用为例。

 

1.ActionScript调用JavaScript:

    这个比较简单,一般都不太会出错,直接用ExternalInterface.call就可以:

  Flex代码:

var temp_str :String= new String(ExternalInterface.call("winClose",aa));

 这里的winClose表明将要调用的JavaScript方法,aa是参数

  JavaScript:

 

function winClose(upData){
    alert(upData);
    return upData;
}

 2.JavaScript调用ActionScript3:

 

     这里我是采用http://www.coolcode.cn/show-291-1.html 上介绍的方法,就是首先在 js 中设置两个标志,例如 jsReady 和 swfReady 这两个变量作为标志,开始都设置为 false,当 window.onload 时,设置 jsReady 为 true,在 Flash 中一开始检查 JavaScript 中的这个 jsReady 标志是否是 true(通过 ExternalInterface.call 方法调用 JavaScript 中的返回这个标志的一个函数),如果不为 true,就设置一个定时器,经过一段时间后(例如 50 或 100 毫秒)重复这个检查这个标志,一旦为 true,则执行 ExternalInterface.addCallback 来发布 ActionScript 要提供给 JavaScript 调用的函数或方法,执行完所有的 ExternalInterface.addCallback 后,通过 ExternalInterface.call 方法调用 JavaScript 中的设置 swfReady 标志的函数设置 swfReady 为 true。之后,当 JavaScript 检测到 swfReady 为 true 后,再调用 ActionScript 中的方法。

好了,看看Flex代码:

			import mx.controls.Alert;
			import flash.events.MouseEvent;
			import flash.external.ExternalInterface;
			import flash.utils.Timer;
			import flash.events.TimerEvent;
			
			internal var aa:String ="你好";
			internal var jsReady:Boolean;
			internal var timer:Timer = new Timer(1000,60);
			internal function initApp():void{
				var externalAvailable:Boolean = ExternalInterface.available;
				this.tip_txt.text="当前的 Flash Player 是否位于提供外部接口的容器:"+externalAvailable;
				btn.addEventListener(MouseEvent.CLICK,handler);
			}
			internal function handler(evt:MouseEvent):void{
				
				var temp_str :String= new String(ExternalInterface.call("winClose",aa));
				jsReady = new Boolean(ExternalInterface.call("JSReady",aa));
				Alert.show(temp_str+","+jsReady,"提示信息",Alert.YES| Alert.NO);
				if(!jsReady){
					
					timer.addEventListener(TimerEvent.TIMER,timerHandler);
					timer.start();
				}else{
					ExternalInterface.addCallback("sayHello",sayHello);
					ExternalInterface.call("setSwfReady",true);
					this.tip_txt.text = "setSwfReady is invoked and set to true;sayHello is added to ExternalInterface.";
				}
				
			}
			internal function timerHandler(evt:TimerEvent):void{
				jsReady = new Boolean(ExternalInterface.call("JSReady",""));
				if(jsReady){
					timer.stop();
				}
			}
			
			public function sayHello(txt:String):void{
				this.tip_txt.text="JS调用ActionScript成功!这是从JavaScript端传递过来的值: "+txt;
			}

 上面是全部的AS代码,下面是对应的HTML代码(全):

<!-- saved from url=(0014)about:internet -->
<html>

<!-- 
Smart developers always View Source. 

This application was built using Adobe Flex, an open source framework
for building rich Internet applications that get delivered via the
Flash Player or to desktops via Adobe AIR. 

Learn more about Flex at http://flex.org 
// -->

<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />

<!--  BEGIN Browser History required section -->
<link rel="stylesheet" type="text/css" href="history/history.css" />
<!--  END Browser History required section -->

<title></title>
<script src="AC_OETags.js" language="javascript"></script>

<!--  BEGIN Browser History required section -->
<script src="history/history.js" language="javascript"></script>
<!--  END Browser History required section -->

<style>
body { margin: 0px; overflow:hidden }
</style>
<script language="JavaScript" type="text/javascript">
<!--
// -----------------------------------------------------------------------------
// Globals
// Major version of Flash required
var requiredMajorVersion = 9;
// Minor version of Flash required
var requiredMinorVersion = 0;
// Minor version of Flash required
var requiredRevision = 28;
// -----------------------------------------------------------------------------
// -->
</script>

<script language="JavaScript" type="text/javascript">
	var jsReady=false;
	var swfReady=false;
	function atReady(){
		jsReady=true;
	}
	function JSReady(){
		return jsReady;
	}
	function setSwfReady(ready){
		swfReady=ready;
	}
	function callAS(){
		if(swfReady){
			var value=document.getElementById('clientValue').value;
			if(value){
				HelloWorld.sayHello(value);
			}else{
				HelloWorld.sayHello("Hello,World");
			}
			
		}else{
			alert("swfReady is: "+ swfReady);
		}
	}
</script>
</head>

<body scroll="no" οnlοad="atReady();">
<script language="JavaScript" type="text/javascript">
function winClose(upData){
    alert(upData);
    return upData;
}

</script>


<script language="JavaScript" type="text/javascript">
<!--
// Version check for the Flash Player that has the ability to start Player Product Install (6.0r65)
var hasProductInstall = DetectFlashVer(6, 0, 65);

// Version check based upon the values defined in globals
var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);

if ( hasProductInstall && !hasRequestedVersion ) {
	// DO NOT MODIFY THE FOLLOWING FOUR LINES
	// Location visited after installation is complete if installation is required
	var MMPlayerType = (isIE == true) ? "ActiveX" : "PlugIn";
	var MMredirectURL = window.location;
    document.title = document.title.slice(0, 47) + " - Flash Player Installation";
    var MMdoctitle = document.title;

	AC_FL_RunContent(
		"src", "playerProductInstall",
		"FlashVars", "MMredirectURL="+MMredirectURL+'&MMplayerType='+MMPlayerType+'&MMdoctitle='+MMdoctitle+"",
		"width", "800",
		"height", "600",
		"align", "middle",
		"id", "HelloWorld",
		"quality", "high",
		"bgcolor", "#869ca7",
		"name", "HelloWorld",
		"allowScriptAccess","sameDomain",
		"type", "application/x-shockwave-flash",
		"pluginspage", "http://www.adobe.com/go/getflashplayer"
	);
} else if (hasRequestedVersion) {
	// if we've detected an acceptable version
	// embed the Flash Content SWF when all tests are passed
	AC_FL_RunContent(
			"src", "HelloWorld",
			"width", "800",
			"height", "600",
			"align", "middle",
			"id", "HelloWorld",
			"quality", "high",
			"bgcolor", "#869ca7",
			"name", "HelloWorld",
			"allowScriptAccess","sameDomain",
			"type", "application/x-shockwave-flash",
			"pluginspage", "http://www.adobe.com/go/getflashplayer"
	);
  } else {  // flash is too old or we can't detect the plugin
    var alternateContent = 'Alternate HTML content should be placed here. '
  	+ 'This content requires the Adobe Flash Player. '
   	+ '<a href=http://www.adobe.com/go/getflash/>Get Flash</a>';
    document.write(alternateContent);  // insert non-flash content
  }
// -->
</script>
<noscript>
  	<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="HelloWorld" width="800" height="600"
			codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
			<param name="movie" value="HelloWorld.swf" />
			<param name="quality" value="high" />
			<param name="bgcolor" value="#869ca7" />
			<param name="allowScriptAccess" value="sameDomain" />
			<embed src="HelloWorld.swf" quality="high" bgcolor="#869ca7"
				width="800" height="600" name="HelloWorld" align="middle"
				play="true"
				loop="false"
				quality="high"
				allowScriptAccess="always"
				type="application/x-shockwave-flash"
				pluginspage="http://www.adobe.com/go/getflashplayer">
			</embed>
	</object>
</noscript>

<div>
<input id="clientValue" type="text" size=20 /><input type="button" οnclick="callAS();" value="JS2AS" />
</div>

</body>
</html>
 

    3.遇到的问题:

 

 

     1)ExternalInterface的参数个数问题:

 

         与跟 Flash 8 中跟 ActionScript 2.0 交互所使用的 flash.external.ExternalInterface 还是有所不同的。最大的不同就是 ExternalInterface.addCallback 方法在 ActionScript 3.0 中只有 2 个参数了,而不再有 instance 这个参数。

     2)JavaScript 调用 Flash 中的 ActionScript 方法时报告该方法不存在:

 

     这个问题是跟 Flash 中执行 ExternalInterface.addCallback 的时间有关的,ExternalInterface.addCallback 必须要在 HTML 的完全载入之后也就是 window.onload 事件执行后才可以执行,否则,它所发布的方法都无法在 JavaScript 中调用。

     另外,在调用AS3暴露的接口时,还必须指定flashObject的id,即必须使用类似这样的方法进行调用:

 

var callResult = flashObject.myFunction("my name");

 

 

   3)动态创建的Flash对象在IE上的问题:

 

      如果你是通过 JavaScript 动态创建的 Flash 标签然后插入到 html 中的话(例如通过 innerHTML 赋值的方法或者 appendChild 的方法),很可能你这个操作是在 window.onload 之后才进行,在这种情况下,其它浏览器可以正常进行 JavaScript 和 ActionScript 3.0 的交互,IE 就不行。所以,为了保险,最好的方法就是直接把 flash 标签的 html 写在 html 的 body 中,或者用 JavaScript 的 document.write 来写入 html 的 body 中,后面这种方法对于 IE 来说更合适一些,因为这样的话,可以不需要点击激活 Flash。

    另一个问题是,不要在 ActionScript 中发布名字为 invoke 的方法,否则在 IE 中,JavaScript 调用该方法时会出错。

 

   4)Flash放在form中的问题:

 

    不要把 flash 放到 form 中,否则在 IE 中,JavaScript 调用 ActionScript 时会出错。当然,网上也给出了一个解决这个问题的脚本 ,不过那个貌似是针对 Flash 8 的 ActionScript 2.0 的,我没有试过,不知道对 ActionScript 3.0 是否同样有效。

 

 

   5) 参数中含有 \的问题:

 

     如果为 HTML 页中的 Flash Player 实例指定的名称(object 标签的 id 属性)包含连字符 (-)
   或在 JavaScript 中定义为运算符的其它字符(如 +、*、/、\、. 等),则在 Internet Explorer
中查看容器网页时,将无法从 ActionScript 调用 ExternalInterface。

      如果在 ActionScript 中通过 ExternalInterface.call 调用 JavaScript 时,如果传递的参数有字符串,那么字符串中如果包含 \ 符号的话,那么将会调用失败。这个也是 ActionScript 和 JavaScript 交互的一个 bug,解决办法是,对传递的字符串先进行一下处理在传递,处理方法很简单,比如要传递的数据是 data,将它进行一次 data.replace(/\\/, “\\\\”) 替换之后,在传递给 JavaScript 就可以了。

 

 下载:

    见附件

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值