JavaScript разговаривает с Flash через ExternalInterface - PullRequest
2 голосов
/ 29 марта 2011

Я пытался собрать доказательство концепции JavaScript, говорящего с Flash. Я использую JQuery и Flash CS5, ActionScript 3.

Я не являюсь разработчиком Flash, поэтому извиняюсь за код, если я докажу, что это работает, Flash будет отдан тому, кто знает, что они делают.

Actionscript находится на слое на временной шкале в первом кадре, с парой элементов в корневом фильме:

output = new TextField();
output.y = -200;
output.x = -200;
output.width = 450;
output.height = 325;
output.multiline = true;
output.wordWrap = true;
output.border = true;
output.text = "Initializing...\n";
root.bgClip.addChild(output); 
try{
     Security.allowDomain("*");
     flash.external.ExternalInterface.marshallExceptions = true;
     output.appendText("External Interface Available? " + ExternalInterface.available + "\n");
     output.appendText("External Interface ObjectId: " + ExternalInterface.objectID + "\n");
     flash.external.ExternalInterface.addCallback("getMenuItems", returnMenuItems);
     flash.external.ExternalInterface.addCallback("changeText", changeText);
     flash.external.ExternalInterface.addCallback("changeBgColour", changeBgColour);
     flash.external.ExternalInterface.call("populateMenu", returnMenuItems());
} catch (error:SecurityError) {
    output.appendText("Security Error: " + error.message + "\n");
} catch (error:Error) {
    output.appendText("Error: " + error.message + "\n");
}
function returnMenuItems():String{
    return "[{\"menu option\": \"javascript:callFlash('changeBgColour','4CB9E4')\"}]";
}
function changeText(t:String){
    root.textClip.text = t;
}
function changeBgColour(colour:String) {
     var c:ColorTransform = root.bgClip.transform.colorTransform;
     c.color = uint(colour);
     root.bgClip.transform.colorTransform = c;
}

JavaScript и HTML:

function populateMenu(message){
    $("#options").changeType("Options", $.parseJSON(message));
    $("#options").addMenuActions();
}
function callFlash(methodToCall, param){
    alert("method: " + methodToCall + ", param: " + param);
    if(param == undefined){
        $("#AJC")[methodToCall]();
    }else{
        $("#AJC")[methodToCall](param);
    }
}
var flashvars = {};
var params = {allowScriptAccess: "always"};
var attributes = {name: "AJC"};
swfobject.embedSWF("http://192.168.184.128/ActionscriptJavascriptCommunication.swf", "AJC", "600", "400", "9", "", flashvars, params, attributes);

и

<body>
  <div id="wrapper">
    <div id="topBar" class="top-bar"></div>
    <div id="flashContainer">
      <div id="AJC">Loading Flash...</div>
    </div>
    <ul class="dropdown" id="games"></ul>
    <ul class="dropdown" id="options"></ul>
  </div>
</body>

Теперь я знаю, что ActionScript ужасен, причина, по которой он выглядит так, заключается в том, что я прочитал много веток о возможных проблемах, связанных с обращением к Flash из JavaScript (отсюда домен разрешенной безопасности * и добавление текстового поля отладки). и т.д.).

JavaScript, который я использую, находится внутри тега script в голове. ChangeType и addMenuActions - это просто методы JQuery, которые я добавил. Это просто методы JavaScript, которые были протестированы независимо, но работают.

Вы заметите, что последняя строка моего try-catch в ActionScript:

flash.external.ExternalInterface.call("populateMenu", returnMenuItems());

Это работает, оно заполняет мое меню текстом, отправленным из Flash. Единственное, что не работает, - это попытка вызвать методы, предоставляемые с помощью функции addCallback.

Я получаю предупреждение, которое говорит:

method: changeBgColour, param: 4CB9E4

но ошибка говорит:

Error: $("#AJC")[methodToCall] is not a function
Source File: http://192.168.184.128/test.html#
Line: 88

Я установил локальную виртуальную машину для запуска Apache, которая относится к 192.168.184.128, мне интересно, если это было проблемой, я видел пару потоков, упоминающих, что попытка связаться с флэш-памятью локально не будет работать, что почему я настроил виртуальную машину с Apache?

Есть идеи? Я знаю, что у людей это работает, это очень расстраивает.

Спасибо.

Ответы [ 2 ]

1 голос
/ 29 марта 2011

Простая ошибка: фабричный метод jQuery создает объект jQuery.init, который действует очень похоже на массив. Вам необходимо вызвать метод для фактического элемента DOM, который является первым членом в «массиве».

$('#AJC')[0][methodToCall]

Если бы у вас были проблемы с безопасностью, вы бы вообще не могли общаться между Flash и JavaScript.

0 голосов
/ 27 апреля 2011

Проблема в том, как вы обращаетесь к своему флеш-объекту. SwfObject имеет встроенную функцию, которая позаботится об этом, она прекрасно работает во всех браузерах:

function callFlash(methodToCall, param)
{
    var obj = swfobject.getObjectById("AJC");

    if(param == undefined){
        $(obj)[methodToCall]();
    }else{
        $(obj)[methodToCall](param);
    }
}

Я не тестировал приведенный выше код, но думаю, он должен работать!

...