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仅仅只是可用而已,不够成熟

作者: 发表于August 21, 2006 at 7:52 am

版权信息: 可以任意转载, 转载时请务必以超链接形式标明文章原始出处作者信息及此声明

Tags: ,

2 条评论 »

  1. topbabys 于 2009-04-16 @ 09:09:20 留言

    不错,正要试一下

  2. ilsanbao 于 2009-04-22 @ 10:12:59 留言

    博主功力深厚啊!

RSS 为此帖反馈评论 · 反向跟踪 网站

留条评论