Я работаю над Flash-игрой, которая должна вызвать Javascript на странице и получить от нее данные. Вызов Javascript из Flash работает. Вызов функций Flash из Javascript (часто) этого не делает.
Я использую Gaia Framework .
Что происходит:
- SWF загружен SWFObject
- В файле Flash есть кнопка. При нажатии он использует
ExternalInterface.call()
для вызова функции Javascript. Это работает.
- Функция Javascript вызывает функцию Flash, которая была открыта с помощью
ExternalInterface.addCallback()
.
- Иногда , 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
. При возникновении ошибки JS блок catch
не запускается . Это тихая ошибка.
- Ошибка возникает при тестировании на веб-хосте, когда SWF-файл загружается с того же сервера, что и страница, на которой он находится.
- Я установил
allowScriptAccess = always
.
- Настройка
flash.system.Security.allowDomain("mydomain")
не исправляет ошибку.
С моей страницы класса:
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(); }
});