javascript - 使用 ExternalInterface.addCallback 注册的函数在 Javascript 中不可用

标签 javascript flash actionscript-3 swfobject externalinterface

我正在开发一个 Flash 游戏,它需要在页面上调用一些 Javascript 并从中获取数据。从 Flash 调用 Javascript 是可行的。从 Javascript 调用 Flash 函数(通常)不会。

我正在使用 Gaia framework .

发生了什么:

  1. 使用 SWFObject 加载 swf
  2. Flash 文件中有一个按钮。单击时,它使用 ExternalInterface.call() 调用 Javascript 函数。 这行得通。
  3. Javascript 函数调用通过 ExternalInterface.addCallback() 公开的 Flash 函数。
  4. 有时,Javascript 会产生以下错误:TypeError: myFlash.testCallback is not a function
  5. 当错误发生时,它会影响使用 addCallback() 注册的所有 函数。 Gaia 及其包含的一些库使用 addCallback(),从 Javascript 调用这些函数也会产生 TypeError。
  6. 在 Flash 中按下按钮之前等待很长时间并不能解决错误。
  7. 让 Flash 定期重试 addCallback() 并不能解决错误
  8. 发生错误时,ExternalInterface.available = trueExternalInterface.objectID 包含 Flash 嵌入对象的正确名称。
  9. 发生错误时,document.getElementById('myflashcontent') 正确返回 Flash 嵌入对象。

编辑添加:

  • 此问题会出现在 Firefox 3.6 中,但不会出现在 Chrome 或 IE8 中。我没有尝试过旧版浏览器。
  • 我正在运行调试版的 Flash 播放器。
  • 我对 ExternalInterface.addCallback() 的调用包含在 try...catch block 中。当 JS 错误发生时,catch block 不会被触发。这是无声的失败。
  • 在网络主机上进行测试时发生错误,swf 加载自与其所在页面相同的服务器。
  • 我设置了 allowScriptAccess = always
  • 设置 flash.system.Security.allowDomain("mydomain") 无法修复错误。

来 self 的页面类:

public class MyPage extends AbstractPage
{
    // declarations of stage instances and class variables

    // other functions

    override public function transitionIn():void 
    {
        send_button.addEventListener(MouseEvent.MOUSE_UP, callJS);
        exposeCallbacks();

        super.transitionIn();
    }

    private function exposeCallbacks():void
    {
        trace("exposeCallbacks()");
        if (ExternalInterface.available) {
            trace("ExternalInterface.objectID: " + ExternalInterface.objectID);
            try {
                ExternalInterface.addCallback("testCallback", simpleTestCallback);
                trace("called ExternalInterface.addCallback");
            }
            catch (error:SecurityError) {
                trace("A SecurityError occurred: " + error.message + "\n");
            }
            catch (error:Error) {
                trace("An Error occurred: " + error.message + "\n");
            }
        }
        else {
            trace("exposeCallbacks() - ExternalInterface not available");
        }
    }

    private function simpleTestCallback(str:String):void
    {
        trace("simpleTestCallback(str=\"" + str + "\")");
    }

    private function callJS(e:Event):void
    {
        if (ExternalInterface.available) {
            ExternalInterface.call("sendTest", "name", "url");
        }
        else {
            trace("callJS() - ExternalInterface not available");
        }
    }

}

我的Javascript:

function sendTest(text, url) {
    var myFlash = document.getElementById("myflashcontent");

    var callbackStatus = "";
    callbackStatus += '\nmyFlash[testCallback]: ' + myFlash['testCallback'];
    //console.log(callbackStatus);

    var errors = false;
    try {
        myFlash.testCallback("test string");
    }
    catch (err) {
        alert("Error: " + err.toString());
        error = true;
    }

    if (!error) {
        alert("Success");
    }
}

var params = {
    quality: "high",
    scale: "noscale",
    wmode: "transparent",
    allowscriptaccess: "always",
    bgcolor: "#000000"
};
var flashVars = {
    siteXML: "xml/site.xml"
};
var attributes = {
    id: "myflashcontent",
    name: "myflashcontent"
};

// load the flash movie.
swfobject.embedSWF("http://myurl.com/main.swf?v2", "myflashcontent",
"728", "676", "10.0.0", serverRoot + "expressInstall.swf",
flashVars, params, attributes, function(returnObj) {
    console.log('Returned ' + returnObj.success);
    if (returnObj.success) { returnObj.ref.focus(); }
});

最佳答案

通过 ExternalInterface 对 JS 的调用被包装在 try { } block 中,这会导致后续的 JS 错误被抑制。

同样的解决方法是在 JavaScript 中导致函数关闭并在超时后执行实际代码。

例子:

function myFnCalledByEI (arg1, arg2) {

    setTimeout(myActualFunction () {
       // You can use arg1 and arg2 here as well!
       // Errors raised within this function will not be
       // suppressed.
    }, 0);

};

关于javascript - 使用 ExternalInterface.addCallback 注册的函数在 Javascript 中不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2634095/

相关文章:

javascript - 需要 javascript 将 RADcombobox 的选定索引设置为 0

javascript - 使用ScriptBundle可以调试吗?

javascript - 是否有 UnicodeData.txt 的官方副本可通过 HTTP 使用 CORS 访问?

flash - Adobe 和浏览器都将终止 Adob​​e Flash 后,有什么方法可以运行 Web 应用程序

apache-flex - 如何以编程方式从 flex 组件中删除验证

java - 计算十六进制颜色相反的公式 ("Difference")

javascript - Foundation 6 change.zf.slider 事件未触发

flash - 我怎样才能使用 CSS3 实现相同的导航? (目前闪存 AS3)

audio - 更改 Flash Player 音频输出设备

apache-flex - Flash/Flex 之外的 Actionscript 3