<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>影の域 &#187; ActionScript</title>
	<atom:link href="http://www.zfkun.com/blog/index.php/archives/category/code/actionscript/feed" rel="self" type="application/rss+xml" />
	<link>http://www.zfkun.com/blog</link>
	<description>时光真的如水...</description>
	<lastBuildDate>Thu, 29 Apr 2010 06:43:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>JavaScript 与 ActionScript 3.0 交互的一些问题</title>
		<link>http://www.zfkun.com/blog/index.php/archives/49</link>
		<comments>http://www.zfkun.com/blog/index.php/archives/49#comments</comments>
		<pubDate>Sat, 16 Jan 2010 15:30:34 +0000</pubDate>
		<dc:creator>影之迷惑</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[as]]></category>
		<category><![CDATA[ExternalInterface]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[交互]]></category>
		<category><![CDATA[通信]]></category>

		<guid isPermaLink="false">http://www.zfkun.com/blog/?p=49</guid>
		<description><![CDATA[JavaScript 跟 ActionScript 3.0 交互也是通过 flash.external.ExternalInterface 这个类，不过与跟 Flash 8 中跟 ActionScript 2.0 交互所使用的 flash.external.ExternalInterface 还是有所不同的。最大的不同就是 ExternalInterface.addCallback 方法在 ActionScript 3.0 中只有 2 个参数了，而不再有 instance 这个参数。下面要讨论的这些问题都是关于 Flash 9 中 ActionScript 3.0 的。]]></description>
			<content:encoded><![CDATA[<p><span style="background-color: #ffffff;">JavaScript 跟 ActionScript 3.0 交互也是通过 flash.external.ExternalInterface 这个类，不过与跟 Flash 8 中跟 ActionScript 2.0 交互所使用的 flash.external.ExternalInterface 还是有所不同的。最大的不同就是 ExternalInterface.addCallback 方法在 ActionScript 3.0 中只有 2 个参数了，而不再有 instance 这个参数。下面要讨论的这些问题都是关于 Flash 9 中 ActionScript 3.0 的。</span></p>
<p>先来说最常遇到的问题，就是在 JavaScript 调用 Flash 中的 ActionScript 方法时报告该方法不存在。这个问题是跟 Flash 中执行 ExternalInterface.addCallback 的时间有关的，ExternalInterface.addCallback 必须要在 HTML 的完全载入之后也就是 window.onload 事件执行后才可以执行，否则，它所发布的方法都无法在 JavaScript 中调用。</p>
<p>解决这个问题的方法在 Flash 9 的 ActionScript 3.0 帮助中有个例子，里面包含了这个解决方法，就是首先在 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 中的方法就不会遇到上的说的这个问题了。</p>
<p>如果简单一点的调用这样还可以，如果是有好多这样的调用就比较麻烦了。我是通过建立两个执行队列：jsTaskQueue 和 swfTaskQueue，当在 jsReady 为 true 之前，如果有要调用 ActionScript 的操作，就把这个操作放到 jsTaskQueue 中，当 js 在 window.onload 中执行设置 jsReady 时，把这个队列中的任务取出来执行，当 jsReady 为 true 后 swfReady 为 true 之前，如果有要调用 ActionScript 的操作，就把这个操作放到 swfTaskQueue 中，当 ActionScript 通过 ExternalInterface.call 方法调用 JavaScript 中的设置 swfReady 标志的函数设置 swfReady 为 true 时，把这个队列中的任务取出来执行。当 jsReady 和 swfReady 都为 true 时，那么如果有要调用 ActionScript 的操作，直接运行就可以了。通过这种方法把这些任务封装后，使用这些封装之后的操作，在编写代码就可以按照顺序（而不是异步）来写了，执行时也是顺序执行啦。</p>
<p>除了这个最常遇到的问题之外，还有两个关于 IE 上的问题。</p>
<p>如果你是通过 JavaScript 动态创建的 Flash 标签然后插入到 html 中的话（例如通过 innerHTML 赋值的方法或者 appendChild 的方法），很可能你这个操作是在 window.onload 之后才进行，在这种情况下，其它浏览器可以正常进行 JavaScript 和 ActionScript 3.0 的交互，IE 就不行。所以，为了保险，最好的方法就是直接把 flash 标签的 html 写在 html 的 body 中，或者用 JavaScript 的 document.write 来写入 html 的 body 中，后面这种方法对于 IE 来说更合适一些，因为这样的话，可以不需要点击激活 Flash。</p>
<p>另一个问题是，不要在 ActionScript 中发布名字为 invoke 的方法，否则在 IE 中，JavaScript 调用该方法时会出错。</p>
<p>最后一个问题，网上可以查到的比较多了，就是不要把 flash 放到 form 中，否则在 IE 中，JavaScript 调用 ActionScript 时会出错。当然，网上也给出了一个<a href="http://livedocs.adobe.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&amp;file=00002200.html">解决这个问题的脚本</a>，不过那个貌似是针对 Flash 8 的 ActionScript 2.0 的，我没有试过，不知道对 ActionScript 3.0 是否同样有效。</p>
<p>如果在 ActionScript 中通过 ExternalInterface.call 调用 JavaScript 时，如果传递的参数有字符串，那么字符串中如果包含 \ 符号的话，那么将会调用失败。这个也是 ActionScript 和 JavaScript 交互的一个 bug，解决办法是，对传递的字符串先进行一下处理在传递，处理方法很简单，比如要传递的数据是 data，将它进行一次 data.replace(/\\/, “\\\\”) 替换之后，在传递给 JavaScript 就可以了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zfkun.com/blog/index.php/archives/49/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
