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之前:

CODE:
  1. <script type="text/javascript">
  2. function ExternalInterfaceManager()
  3. {
  4.     this.registerMovie = function(movieName) {
  5.         if(!window.fakeMovies) window.fakeMovies = new Array();
  6.         window.fakeMovies[window.fakeMovies.length] = movieName;
  7.     }
  8.     this.initialize = function() {
  9.         if(document.all)
  10.         {
  11.             if(window.fakeMovies)
  12.             {
  13.                 for(i=0;i<window.fakeMovies.length;i++)
  14.                 {
  15.                     window[window.fakeMovies[i]] = new Object();
  16.                 }
  17.                 window.onload = initializeExternalInterface;
  18.             }
  19.         }
  20.  
  21.     }
  22. }
  23. function initializeExternalInterface() {
  24.     for(i=0;i<window.fakeMovies.length;i++) {
  25.         var movieName = window.fakeMovies[i];
  26.         var fakeMovie = window[movieName];
  27.         var realMovie = document.getElementById(movieName);
  28.  
  29.         for(var method in fakeMovie) {
  30.             alert(arguments);
  31.             realMovie[method] = function() {flashFunction = "<invoke name=\"" + method.toString() + "\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments, 0) + "</invoke>";this.CallFunction(flashFunction);}
  32.         }
  33.  
  34.         window[movieName] = realMovie;
  35.     }
  36. }
  37. var eim = new ExternalInterfaceManager();
  38. eim.registerMovie("ShockwaveFlash1");
  39. eim.registerMovie("ShockwaveFlash2");
  40. eim.initialize();
  41. </script>

这样就可以一定程度上解决ExternalInterface在form标签之间会报错的问题,是asp.net开发者的福音。

原理

下面是浏览器载入一个包含ExternalInterface调用的flash之后,flash player可能会用到的方法

CODE:
  1. function __flash__arrayToXML(obj) {
  2.     var s = "<array>";
  3.     for (var i=0; i<obj.length; i++) {
  4.         s += "<property id=\"" + i + "\">" + __flash__toXML(obj[i]) + "</property>";
  5.     }
  6.     return s+"</array>";
  7. }
  8. function __flash__argumentsToXML(obj,index) {
  9.     var s = "<arguments>";
  10.     for (var i=index; i<obj.length; i++) {
  11.         s += __flash__toXML(obj[i]);
  12.     }
  13.     return s+"</arguments>";
  14. }
  15. function __flash__objectToXML(obj) {
  16.     var s = "<object>";
  17.     for (var prop in obj) {
  18.         s += "<property id=\"" + prop + "\">" + __flash__toXML(obj[prop]) + "</property>";
  19.     }
  20.     return s+"</object>";
  21. }
  22. function __flash__escapeXML(s) {
  23.     return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
  24. }
  25. function __flash__toXML(value) {
  26.    var type = typeof(value);
  27.     if (type == "string") {
  28.         return "<string>" + __flash__escapeXML(value) + "</string>";
  29.     } else if (type == "undefined") {
  30.         return "<undefined/>";
  31.     } else if (type == "number") {
  32.         return "<number>" + value + "</number>";
  33. }

可以认为现在的ExternalInterface Class仅仅只是可用而已,不够成熟

作者: Volcano 发表于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 为此帖反馈评论 · 反向跟踪 网站

留条评论