flash和javascript之间的交互 —— ExternalInterface
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
最近做一个应用,flash和javascript之间互有调用。最后一次写点Actionscript也是在flash 7的时候了,因此按照我的想法,只要用fscommand和getUrl("javasciprt:.......")这种形式,flash和javascript之间互相调用应该不是什么大问题。
没多久就开始觉着自己落后了,Flash 8早已经新增了ExternalInterface API专门处理flash与外部应用的交互,只要浏览器装有flash player,支持的范围应是更广。
ExternalInterface class能够运行的环境
- Internet Explorer for Windows (5.0 and later)
- Firefox 1.0 and later
- Mozilla 1.7.5 and later
- Netscape 8.0 and later
- Safari 1.3 and later.
使用心得
ExternalInterface class仅仅只有两个方法:
- addCallback(methodName:String, instance:Object, method:Function) : Boolean
Registers an ActionScript method as callable from the container. - call(methodName:String, [parameter1:Object]) : Object
Calls a function exposed by the Flash Player container, passing 0 or more arguments.
这两个方法的使用在手册有详细说明,使用范例可以从flash的安装路径例如C:\Program Files\Macromedia\Flash 8\Samples and Tutorials\Samples\ActionScript\ExternalAPI下面找到,没太大悬念。
碰到的问题
在IE浏览器下,将flash对象放在form标签之间,ExternalInterface class就会给你报javascript错,而firefox下完全正常,这简直是让人很郁闷的事情,折腾了一天才找到问题原因,可能是IE的Bug吧,这个在livedoc上有人反映过类似的问题。见下面的url:
http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002200.html
有人提出这样的解决办法,将下面这段javascript放在html里的flash之前:
-
<script type="text/javascript">
-
function ExternalInterfaceManager()
-
{
-
this.registerMovie = function(movieName) {
-
if(!window.fakeMovies) window.fakeMovies = new Array();
-
window.fakeMovies[window.fakeMovies.length] = movieName;
-
}
-
this.initialize = function() {
-
if(document.all)
-
{
-
if(window.fakeMovies)
-
{
-
for(i=0;i<window.fakeMovies.length;i++)
-
{
-
window[window.fakeMovies[i]] = new Object();
-
}
-
window.onload = initializeExternalInterface;
-
}
-
}
-
-
}
-
}
-
function initializeExternalInterface() {
-
for(i=0;i<window.fakeMovies.length;i++) {
-
var movieName = window.fakeMovies[i];
-
var fakeMovie = window[movieName];
-
var realMovie = document.getElementById(movieName);
-
-
for(var method in fakeMovie) {
-
alert(arguments);
-
realMovie[method] = function() {flashFunction = "<invoke name=\"" + method.toString() + "\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments, 0) + "</invoke>";this.CallFunction(flashFunction);}
-
}
-
-
window[movieName] = realMovie;
-
}
-
}
-
var eim = new ExternalInterfaceManager();
-
eim.registerMovie("ShockwaveFlash1");
-
eim.registerMovie("ShockwaveFlash2");
-
eim.initialize();
-
</script>
这样就可以一定程度上解决ExternalInterface在form标签之间会报错的问题,是asp.net开发者的福音。
原理
下面是浏览器载入一个包含ExternalInterface调用的flash之后,flash player可能会用到的方法
-
function __flash__arrayToXML(obj) {
-
var s = "<array>";
-
for (var i=0; i<obj.length; i++) {
-
s += "<property id=\"" + i + "\">" + __flash__toXML(obj[i]) + "</property>";
-
}
-
return s+"</array>";
-
}
-
function __flash__argumentsToXML(obj,index) {
-
var s = "<arguments>";
-
for (var i=index; i<obj.length; i++) {
-
s += __flash__toXML(obj[i]);
-
}
-
return s+"</arguments>";
-
}
-
function __flash__objectToXML(obj) {
-
var s = "<object>";
-
for (var prop in obj) {
-
s += "<property id=\"" + prop + "\">" + __flash__toXML(obj[prop]) + "</property>";
-
}
-
return s+"</object>";
-
}
-
function __flash__escapeXML(s) {
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
-
}
-
function __flash__toXML(value) {
-
var type = typeof(value);
-
if (type == "string") {
-
return "<string>" + __flash__escapeXML(value) + "</string>";
-
} else if (type == "undefined") {
-
return "<undefined/>";
-
} else if (type == "number") {
-
return "<number>" + value + "</number>";
-
}
可以认为现在的ExternalInterface Class仅仅只是可用而已,不够成熟
作者: Volcano 发表于August 21, 2006 at 7:52 am
topbabys 于 2009-04-16 @ 09:09:20 留言 :
不错,正要试一下
ilsanbao 于 2009-04-22 @ 10:12:59 留言 :
博主功力深厚啊!