2009-09-17 7 views
6

My simple ActionScript Sto tentando di utilizzare il codice ExternalInterface di Flash per impostare un callback in modo che JavaScript possa chiamare un metodo sul mio oggetto Flash. Tutto funziona bene in Safari, Firefox e IE, ma non riesco a far funzionare Chrome. Quando provo il codice su Chrome, ottengo il seguente errore:Problema di accesso al metodo esposto di ExternalInterface in Google Chrome

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

Ecco l'esempio HTML che sto usando (ancora una volta, funziona bene in Safari, FF e 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> 

e qui è l'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

Non correlato al tuo problema, ma dovresti davvero rimuovere quel brutto "navigatore". – kangax

+0

In realtà, Chrome sul mio Mac non genera errori (e sembra impostare correttamente il testo) – kangax

+0

Il tuo diritto, funziona in modo frustrante per me anche su Chromium sul mio Mac. Solo non Chrome su Windows –

risposta

3

Ho lo stesso problema, per attivare e ricevere eventi listener tra javascript e flash.

La soluzione era utilizzare il file AC_OETags.js da Adobe come script di incorporamento invece di JQuery flash. (Si trova nel file zip sotto Rilevamento lato client, probabilmente Adobe lo ha anche in altri posti)

Il problema si basa su una condizione di competizione quando il flash crea i callback javascript nel browser. Questo non è gestito correttamente da un embed dritto per qualche motivo.

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

allora si può fare: (funziona in IE, FF, Safari, Cromo, ++)

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

Mi spiace, potresti per favore elaborare? Gli stai dando un src = "tagflash", quindi id e il nome di "myTagFlash", ma alla fine finisci per chiamarlo tramite id di "tagFlash" (maiuscola F). Volevi digitare '$ (" # myTagFlash "). GotoNewFrame();', giusto? – dimitarvp

+0

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

+0

"allowScriptAccess", "always" fisso, grazie :) –

3

ho avuto problemi con ExternalInterface e Firefox e Chrome e ho scoperto che Adobe script non stava scrivendo il tag Flash abbastanza in fretta, in modo che quando il browser ha cercato di trovare l'ADDC funzione allback() non era lì al momento.

Semplicemente mettendo la mia funzione javascript che chiama il componente aggiuntivo creato da Flash inConback() in una chiamata window.setTimeout() risolve il problema. Ritardi inferiori a 200 ms continuano a causare il problema.

Non ho dovuto utilizzare la soluzione di cercare di trovare se l'attributo "lunghezza" esiste nell'oggetto [FlashId] del documento. Basta chiamare "FlashEmbed = document [FlashId]" ha funzionato bene.

+0

Interessante, dovrò provare che –

+2

mi dispiace @Robson - ma questa non è una buona idea. La condizione di competizione è dovuta al fatto che l'oggetto SWF non viene caricato ed eseguito e non il tag stesso non viene scritto. Potrebbero essere necessari 10 secondi per una connessione lenta per il download di un SWF e il problema potrebbe non essere mai visto sul computer locale perché non si verificheranno ritardi di rete. Si prega di vedere la mia risposta per il modo migliore (ho trovato) per chiamare Flash nel più breve tempo possibile. –

+0

Penso che dovremmo inserire un timer di ripetizione in Flash per verificare se JavaScript è pronto o meno. –

13

Sono d'accordo con Robson sul fatto che si tratti di una condizione di competizione, ma non si tratta di "scrivere il tag Flash" e aggiungere un timer non è una buona soluzione, anzi è molto pericoloso.

Il problema è che il SWF stesso non è stato caricato e ha avuto la possibilità di inizializzare l'interfaccia esterna. Per un piccolo SWF in Chrome, i tempi potrebbero essere più sensibili di altri browser, ma il problema sottostante non è specifico di Chrome.

Quello che dovete fare è questo:

in ActionScript

chiamata questa funzione dal costruttore:

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

nel codice HTML

<script> 

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

</script> 

È possibile trovare sul proprio computer locale che funzioni senza questo, ma non appena si aggiungono ritardi di rete nell'equazione, si pentirà di non farlo. Un timer arbitrario è una cattiva idea perché si otterrà comunque l'errore su una connessione lenta. Questo metodo consente alla pagina di chiamare l'oggetto flash il prima possibile.


Nota: utilizzando jQuery di 'sul pronto' modello non è una soluzione al problema - anche se in un primo momento ho scambiato per uno.

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

anche swfobject di callbackFn non è anche una soluzione becasue che appena ti dice quando si inserisce il tag e non quando il file SWF viene caricato.

+0

grazie per la soluzione anche dopo tutto questo tempo. Dopo un po 'mi sono reso conto che non si trattava di un problema specifico di Chrome, ma piuttosto di cercare di affrettare la richiamata proprio come hai detto. Grazie anche per la soluzione. – Mathias

+0

Ciao Simmon, cosa significa '$ ('# Main') [0] .activate();'? Dov'è '# Main'? –

+1

activate() è solo il nome della funzione nel filmato flash che è stato esposto con ExternalInterface (c'è una funzione activate() non mostrata qui), e Main è l'ID dello swf come creato da swfobject –

0

v'è una soluzione per il problema disattivando Chrome built-in plug in flash:

  1. tipo il chrome: // plugins nella barra degli indirizzi di Chrome.
  2. espandere i dettagli dei plugin facendo clic sui dettagli nell'angolo in alto a destra.
  3. nella voce "Adobe Flash Player", disabilitando il primo.

Questa non è una soluzione, ma mostra perché questo accade su Chrome. Chrome accompagna con plug-in flash incorporati, che spesso causano problemi quando usiamo ExternalInterface di AS3, è fastidioso.

+0

A volte, i plugin incorporati funzionano. Ma dopo l'aggiornamento di Chrome alla nuova versione (ad esempio la versione 28), il plug-in integrato interrompe le chiamate ExternalInterface – zjy

Problemi correlati