Проблема с доступом к внешнему методу ExternalInterface в Google Chrome - PullRequest
6 голосов
/ 17 сентября 2009

Мой простой ActionScript Я пытаюсь использовать ExternalInterface Flash для настройки обратного вызова, чтобы JavaScript мог вызывать метод для моего объекта Flash. Все отлично работает в Safari, Firefox и IE, но я не могу заставить работать Chrome. Когда я пробую код в Chrome, я получаю следующую ошибку:

Uncaught TypeError: Object # не имеет метода 'SetText'

Вот пример HTML, который я использую (опять же, отлично работает в Safari, FF и IE)

<html><body>
<div id="mycontent"></div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<script type="text/javascript">
swfobject.embedSWF("http://invincible.dynalias.com:8080/HelloWorld.swf", "mycontent", "400", "420", "9.0.0","expressInstall.swf", {}, {allowScriptAccess:'always'},{id:'hw',name:'hw'});

function getFlash(movieName) {
   return ( navigator.appName.indexOf("Microsoft") != -1) ? window[movieName] : document.getElementById(movieName);
}
</script><p>
  <input type="text" id="exampleText" /> <input type="button" value="Set Text" onclick="getFlash('hw').setText(document.getElementById('exampleText')
.value)" />
</body>
</html>

и вот ActionScript ...

package {
  import flash.display.Sprite;
  import flash.text.TextField;
  import flash.external.ExternalInterface;
  import flash.system.Security;

  public class HelloWorld extends Sprite {

    private var textField:TextField = new TextField();
    public function HelloWorld() {
      Security.allowDomain("*");
      ExternalInterface.addCallback("setText", this.setText);
      textField.text = "Hello, world!";
      addChild(textField);
    }   
    public function setText(text:String):void {
      this.textField.text = text;
    }   
  }
}

Ответы [ 5 ]

13 голосов
/ 14 марта 2011

Я согласен с Робсоном, что это условие гонки, но дело не в том, чтобы «записать Flash-тег», а добавление таймера не является хорошим решением - на самом деле это очень опасно.

Проблема в том, что сам SWF не загружен и имел возможность инициализировать ваш внешний интерфейс. Для небольших SWF-файлов в Chrome время может быть более чувствительным, чем в других браузерах, но основная проблема не связана с Chrome.

Что вам нужно сделать, это:

В ActionScript

Вызовите эту функцию из вашего конструктора:

public function InitializeExternalInterface():void 
{   
      if (ExternalInterface.available) {

           // register actionscript functions so they can be called by JS   
           ExternalInterface.addCallback("activate", activate);
           Security.allowDomain("www.example.com");     

           // send message to parent page that SWF is loaded and interface active
           trace("External Interface Initialized...");
           ExternalInterface.call("flashInitialized")
      }
      else 
      {
          trace("ERROR: External Interface COULD NOT BE Initialized...");
      } 
}

В вашем HTML

 <script>

     function flashInitialized() 
     {
         alert("Initialized!");      // remove this obviously!
         $('#Main')[0].activate();   // safe to call Flash now
     }

 </script>

На локальном компьютере вы можете обнаружить, что он работает без этого, но как только вы добавите сетевые задержки в уравнение, вы пожалеете, что этого не сделали. Произвольный таймер - плохая идея, потому что вы все равно получите ошибку при медленном соединении. Этот метод позволяет странице вызывать флэш-объект в самое ближайшее время.


Примечание: Использование шаблона «готово» в jQuery НЕ является решением проблемы - хотя сначала я принял его за один.

$(function() 
{
   $('#animation')[0].SetTitle("Hello"); 
} 

Кроме того, swfobject's callbackFn также не является решением, поскольку просто сообщает, когда тег вставлен, а не когда загружен SWF.

3 голосов
/ 18 апреля 2011

У меня возникла та же проблема - запускать и получать события слушателя между javascript и flash.

Решением было использование AC_OETags.js файла от Adobe в качестве сценария для встраивания вместо JQuery flash. (Он находится в zip-файле в разделе «Обнаружение на стороне клиента», возможно, у Adobe есть и другие места)

Проблема, связанная с состоянием гонки, когда флэш-память создает обратные вызовы JavaScript в браузере. По какой-то причине это неправильно обрабатывается прямым вставлением.

<div>
<script>
// Major version of Flash required
var requiredMajorVersion = 10;
// Minor version of Flash required
var requiredMinorVersion = 0;

var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
AC_FL_RunContent(
"src", "tagflash",
    "width", "200",
    "height", "200",
    "id", "myTagFlash",
    "quality", "high",
    "bgcolor", "#FFFFFF",
    "name", "myTagFlash",
    "allowScriptAccess","always",
    "type", "application/x-shockwave-flash",
    "pluginspage", "http://www.adobe.com/go/getflashplayer",
    "flashvars", "templateData=theYear:2010&theTagNumber:123"
);
</script>
</div>

Тогда вы можете сделать: (работает в IE, FF, Safari, Crome, ++)

$("#tagFlash").gotoNewFrame();
3 голосов
/ 08 декабря 2009

У меня были проблемы с ExternalInterface, Firefox и Chrome, и я обнаружил, что Adobe Script недостаточно быстро записывал Flash-тег, поэтому, когда браузер попытался найти функцию addCallback (), его там не было.

Простое помещение моей функции Javascript, которая вызывает созданный Flash метод addCallback () в вызове window.setTimeout (), решает проблему. Задержки менее 200 мс все еще приводят к возникновению проблемы.

Мне не пришлось использовать решение, чтобы найти, существует ли атрибут «length» в объекте документа [FlashId]. Просто вызов «FlashEmbed = document [FlashId]» работал просто отлично.

0 голосов
/ 15 августа 2013

Существует способ обойти эту проблему, отключив встроенный плагин Chrome:

  1. введите chrome: // plugins в адресную строку chrome.
  2. разверните детали плагинов, нажав на детали в правом верхнем углу.
  3. в записи «Adobe Flash Player», отключение первого.

Это не решение, но показывает, почему это происходит в Chrome. Chrome сопровождается встроенными плагинами, которые часто вызывают проблемы при использовании ExternalInterface в AS3, это раздражает.

0 голосов
/ 25 января 2012

После долгих попыток я, наконец, решил использовать официальное решение от Adobe:

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html

Поиск ExternalInterfaceExample.as.

...