2009-09-17 18 views
6

Mój prosty ActionScript Próbuję użyć funkcji Flash ExternalInterface, aby skonfigurować wywołanie zwrotne, aby JavaScript mógł wywoływać metodę w moim obiekcie Flash. Wszystko działa dobrze w Safari, Firefox i IE, ale nie mogę uruchomić Chrome. Kiedy próbuję kod na Chrome, pojawia się następujący błąd:Problem z dostępem do metody narażonej na działanie ExternalInterface w przeglądarce Google Chrome

Uncaught TypeError: Object #<an HTMLObjectElement> has no method 'setText'

Oto przykład HTML używam (znów działa prawidłowo w Safari, FF i 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> 

i tutaj jest 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; 
    } 
    } 
} 
+0

Niezwiązany z twoim problemem, ale powinieneś naprawdę usunąć ten paskudny "navigator" sniff. – kangax

+0

W rzeczywistości Chrome na moim Macu nie generuje żadnych błędów (i wydaje się, że poprawnie ustawia tekst). – kangax

+0

Twoje prawo, to frustrująco działa dla mnie również na Chromium na moim Macu. Po prostu nie Chrome w systemie Windows –

Odpowiedz

3

Mam ten sam problem, aby strzelać i odbierać zdarzenia związane ze słuchaczem między javascript i flash.

Rozwiązaniem było użycie pliku AC_OETags.js z Adobe jako skryptu embedd zamiast flash JQuery. (Znajduje się w pliku zip pod wykrywaniem po stronie klienta, Adobe prawdopodobnie ma też inne miejsca)

Problem związany z warunkami wyścigu, gdy flash buduje wywołania zwrotne javascript w przeglądarce. Nie jest to właściwie udokumentowane przez proste osadzenie z jakiegoś powodu.

<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> 

Następnie można zrobić: (działa w IE, FF, Safari, Crome, ++)

$("#tagFlash").gotoNewFrame(); 
+0

Przepraszam, czy mógłbyś to wyjaśnić? Dajesz mu src = "tagflash", a następnie id i nazwę "myTagFlash", ale ostatecznie na koniec wywołasz go przez id "tagFlash" (duże F). Zamierzałeś wpisać '$ (" # myTagFlash "). GotoNewFrame();', prawda? – dimitarvp

+0

"allowScriptAccess", "always" NOT "allowScriptAccess", "allways" – robertp

+0

"allowScriptAccess", "always" naprawiono, dziękuję :) –

3

miałem problemy z ExternalInterface i Firefox i Chrome i odkrył, że Adobe nie było pisanie skryptów tag Flash wystarczająco szybko, więc gdy przeglądarka próbowali znaleźć ADDC funkcja allback(), której nie było w tym czasie.

prostu oddanie moich funkcji JavaScript, który wywołuje Flash stworzony addCallback() w window.setTimeout() wywołujący rozwiązuje problem. Opóźnienia mniejsze niż 200 ms nadal powodują wystąpienie problemu.

nie trzeba używać rozwiązanie stara się znaleźć, jeżeli atrybut „długość” istnieje w dokumencie [FlashId] obiektu. Po prostu wywołanie "FlashEmbed = document [FlashId]" działało dobrze.

+0

Interesujące, będę musiał spróbować tego –

+2

przepraszam @Robson - ale to nie jest dobry pomysł. Stan wyścigu wynika z tego, że obiekt SWF nie jest ładowany i uruchamiany, a nie sam tag nie jest zapisywany. Usunięcie pliku SWF może zająć 10 sekund w powolnym połączeniu, a problem może pojawić się na komputerze lokalnym, ponieważ nie będzie takich opóźnień w sieci. Zapoznaj się z moją odpowiedzią, aby jak najlepiej (jak się dowiedziałem) zadzwonić do Flasha w najwcześniejszym możliwym terminie. –

+0

Myślę, że powinniśmy umieścić w Flashu programator powtarzania, aby sprawdzić, czy JavaScript jest gotowy, czy nie. –

13

zgadzam się z Robson, że jest to sytuacja wyścigu, ale to nie jest w „pisanie tag Flash” i dodając czasomierza nie jest dobrym rozwiązaniem - w rzeczywistości jego bardzo niebezpieczne.

Problem polega na tym, że sama nie jest załadowany SWF i miał szansę zainicjować interfejsu zewnętrznego. W przypadku małego pliku SWF w Chrome czas może być bardziej wrażliwy niż inne przeglądarki, ale podstawowy problem nie dotyczy tylko przeglądarki Chrome.

Co trzeba zrobić, to:

ActionScript

wywołać tę funkcję od konstruktora:

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..."); 
     } 
} 

w HTML

<script> 

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

</script> 

Możesz znaleźć na komputerze lokalnym, że działa bez tego, ale jak tylko dodasz opóźnienia sieciowe do równania, będziesz żałować, że tego nie zrobiłeś. Dowolny zegar jest złym pomysłem, ponieważ nadal będzie występować błąd podczas wolnego połączenia. Ta metoda umożliwia wywołanie obiektu Flash w najwcześniejszym możliwym czasie.


Uwaga: Korzystanie jQuery jest „gotowy” na wzór nie jest rozwiązaniem problemu - chociaż w pierwszej chwili wziął go za jednego.

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

także swfobject na callbackFn również nie jest rozwiązaniem becasue że po prostu mówi, gdy znacznik jest włożona, a nie wtedy, gdy plik SWF jest załadowany.

+0

dzięki za rozwiązanie nawet po upływie tego czasu. Po jakimś czasie zdałem sobie sprawę, że nie jest to problem specyficzny dla przeglądarki Chrome, ale raczej próba przyspieszenia wywołania zwrotnego, o której wspomniałeś. Dzięki za rozwiązanie. – Mathias

+0

Hi Simmon, co to znaczy '$ ('# Main') [0] .activate();'? Gdzie jest '# Main'? –

+1

activate() to tylko nazwa funkcji w filmie flash, który został odsłonięty za pomocą ExternalInterface (jest tu funkcja activate() nie pokazana tutaj), a Main jest identyfikatorem pliku swf tworzonego przez swfobject –

0

Istnieje obejście problemu poprzez wyłączenie Chrome wbudowane wtyczki Flash:

  1. typu chrome: // plugins w pasku adresu Chrome.
  2. rozwiń szczegóły wtyczek, klikając szczegóły w prawym górnym rogu.
  3. w pozycji "Adobe Flash Player", wyłączając pierwszy.

To nie jest rozwiązanie, ale pokazuje, dlaczego tak się dzieje w Chrome. Chrome towarzyszy wbudowanym wtyczkom flash, które często powodują problemy, gdy używamy ExternalInterface AS3, jest denerwujące.

+0

Czasami działa wbudowane wtyczki. Ale po aktualizacji Chrome do nowej wersji (takiej jak wersja 28) wbudowana wtyczka przerywa wywołania ExternalInterface – zjy