我正在开发一个 Flash 游戏,它需要在页面上调用一些 Javascript 并从中获取数据。从 Flash 调用 Javascript 是可行的。从 Javascript 调用 Flash 函数(通常)不会。
我正在使用 Gaia framework .
发生了什么:
- 使用 SWFObject 加载 swf
- Flash 文件中有一个按钮。单击时,它使用
ExternalInterface.call()
调用 Javascript 函数。 这行得通。 - Javascript 函数调用通过
ExternalInterface.addCallback()
公开的 Flash 函数。 - 有时,Javascript 会产生以下错误:
TypeError: myFlash.testCallback is not a function
。 - 当错误发生时,它会影响使用
addCallback()
注册的所有 函数。 Gaia 及其包含的一些库使用addCallback()
,从 Javascript 调用这些函数也会产生 TypeError。 - 在 Flash 中按下按钮之前等待很长时间并不能解决错误。
- 让 Flash 定期重试
addCallback()
并不能解决错误 - 发生错误时,
ExternalInterface.available = true
和ExternalInterface.objectID
包含 Flash 嵌入对象的正确名称。 - 发生错误时,
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/