Как вызвать динамически создаваемый flash внешний интерфейс в IE из javascript? - PullRequest
7 голосов
/ 28 января 2010

Что у меня есть:

  1. SWF экспортирует функцию через ExternalInterface
  2. Javascript создает новый объект для встраивания и добавляет его в документ
  3. Вызов функции флеш-памяти работает нормально в других браузерах
  4. Сбой вызова функций флэш-памяти в IE 8

Пример экспорта функций в swf:

flash.external.ExternalInterface.addCallback("isActive", ...

Пример создания встраиваемого объекта:

var b = document.createElement('embed');

    b.type = 'application\u002fx-shockwave-flash';
    b.setAttribute('allowFullScreen', 'true');
    b.setAttribute('allowNetworking', 'all');
    b.setAttribute('allowScriptAccess', 'always');
    b.width = 500;
    b.height = 400;
    b.src = 'assets\u002fUltra4.UltraApplication\u002fUltra4.UltraApplication+UltraSprite.swf';

Пример вызова внешнего интерфейса flash в javascript:

   try
    {
      e = b.isActive();
    }
    catch (__exc){ }

В IE он будет ловить с сообщением «Объект не поддерживает это свойство или метод»

Как это исправить?

  1. Похожие: http://bojolais.livejournal.com/251383.html
  2. Похожие: ExternalInterface не работает в IE
  3. Похожие: http://swfupload.org/forum/generaldiscussion/985
  4. Похожие: http://code.google.com/p/doctype/wiki/ArticleFixingFlashExternalInterface
  5. Похожие: http://www.dangerouslyawesome.com/2006/10/20/another-swfobject-problem-deproblemed/
  6. Похожие: http://www.airtightinteractive.com/news/?p=71

В отладчике сценария я вижу сторонний сценарий, который должен быть мостом:

function __flash__arrayToXML(obj) {
    var s = "<array>";
    for (var i=0; i<obj.length; i++) {
        s += "<property id=\"" + i + "\">" + __flash__toXML(obj[i]) + "</property>";
    }
    return s+"</array>";
}
function __flash__argumentsToXML(obj,index) {
    var s = "<arguments>";
    for (var i=index; i<obj.length; i++) {
        s += __flash__toXML(obj[i]);
    }
    return s+"</arguments>";
}
function __flash__objectToXML(obj) {
    var s = "<object>";
    for (var prop in obj) {
        s += "<property id=\"" + prop + "\">" + __flash__toXML(obj[prop]) + "</property>";
    }
    return s+"</object>";
}
function __flash__escapeXML(s) {
    return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
}
function __flash__toXML(value) {
   var type = typeof(value);
    if (type == "string") {
        return "<string>" + __flash__escapeXML(value) + "</string>";
    } else if (type == "undefined") {
        return "<undefined/>";
    } else if (type == "number") {
        return "<number>" + value + "</number>";
    } else if (value == null) {
        return "<null/>";
    } else if (type == "boolean") {
        return value ? "<true/>" : "<false/>";
    } else if (value instanceof Date) {
        return "<date>" + value.getTime() + "</date>";
   } else if (value instanceof Array) {
       return __flash__arrayToXML(value);
   } else if (type == "object") {
       return __flash__objectToXML(value);
   } else {
        return "<null/>"; //???
    }
}
function __flash__addCallback(instance, name) {
  instance[name] = function () { 
    return eval(instance.CallFunction("<invoke name=\""+name+"\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments,0) + "</invoke>"));
  }
}
function __flash__removeCallback(instance, name) {
  instance[name] = null;
}

Ответы [ 3 ]

3 голосов
/ 07 февраля 2010

Я не уверен, правильно ли я понимаю ваш вопрос. Но я думаю, что вам не хватает пары вещей:

1) Ваш тег для вставки нуждается в атрибуте имени. Назовем его «NewFlashMovie» для следующего кода:

b.name = "NewFlashMovie";

2) Вам необходимо по-разному вызывать функцию isActive с помощью внешней функции. Сначала добавьте эту функцию

 function thisMovie(movieName) {
     if (navigator.appName.indexOf("Microsoft") != -1) {
         return window[movieName];
     } else {
         return document[movieName];
     }
 }

Затем вы можете вызвать функцию, как эта

thisMovie("NewFlashMovie").isActive();

По моему опыту, это "thisMovie" необходимо для объединения вызовов IE-Flash. Это также описано в документации ExternalInterface

3) Я также рекомендую использовать swfobject вместо создания собственного объекта для "встраивания".

Надеюсь, это поможет.

1 голос
/ 05 марта 2010

Я обнаружил, что для IE, вызывающего Javascript из ActionScript, мне нужно было указать атрибут "id" для тега object . Способ обработки ExternalInterface.call (...) в IE заключается в вызове метода для объекта . IE выдает код

document.getElementById("...").SetReturnValue(...)

Без атрибута id на вашем объектном теге это уменьшается до

document.getElementById("").SetReturnValue(...)

, который пытается вызвать SetReturnValue для нулевого объекта.

Обратите внимание, что атрибут "id" не требуется для других браузеров, но на самом деле он также не вреден.

В вашем случае может происходить нечто подобное: возможно, атрибут "name" в embed может помочь.

0 голосов
/ 07 февраля 2010

Может ли это быть связано с тем, что вы создаете тег Embed вместо тега Object? IE традиционно использует теги объектов для встраивания содержимого Flash

См. Технологию Adobe для обсуждения: http://kb2.adobe.com/cps/415/tn_4150.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...