2009-09-17 14 views
6

Mi simple ActionScript Estoy tratando de usar Flash ExternalInterface para configurar una devolución de llamada para que JavaScript pueda llamar a un método en mi objeto Flash. Todo funciona bien en Safari, Firefox y en IE, pero no puedo hacer que Chrome funcione. Cuando intento el código en Chrome, me sale el siguiente error:Problema al acceder al método expuesto ExternalInterface en Google Chrome

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

Aquí está el código HTML ejemplo estoy usando (de nuevo, funciona bien en Safari, FF y 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> 

y aquí es el 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

No relacionado con su problema, pero en realidad debería eliminar ese asqueroso 'navegador' olfateo. – kangax

+0

En realidad, Chrome en mi Mac no arroja ningún error (y parece configurar el texto correctamente) – kangax

+0

Tiene razón, me resulta frustrante para Chromium en mi Mac también. Simplemente no Chrome en Windows –

Respuesta

3

Tengo el mismo problema, disparar y recibir eventos de escucha entre javascript y flash.

La solución fue utilizar el archivo AC_OETags.js de Adobe como secuencia de comandos incrustada en lugar de JQuery. (Se encuentra en el archivo zip en Detección del lado del cliente, Adobe probablemente también en algunos otros lugares)

El problema se basa en una condición de carrera cuando el flash genera las devoluciones de llamada de javascript en el navegador. Esto no se maneja correctamente con una inserción recta por alguna razón.

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

entonces usted puede hacer: (funciona en IE, FF, Safari, Crome, ++)

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

Lo siento, ¿podrían explicarlo? Le está dando un src = "tagflash", luego id y el nombre de "myTagFlash", pero al final usted termina llamando a través de id de "tagFlash" (mayúscula F). Querías escribir '$ (" # myTagFlash "). GotoNewFrame();', ¿verdad? – dimitarvp

+0

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

+0

"allowScriptAccess", "always" fixed, thank you :) –

3

que estaba teniendo problemas con ExternalInterface y Firefox y Chrome y descubrí que la secuencia de comandos de Adobe no estaba escribiendo la etiqueta de flash con la suficiente rapidez, por lo que cuando el navegador trataron de encontrar el ADDC la función allback() no estaba allí en ese momento.

Simplemente poniendo mi función de Javascript que llama al Flash creado addCallback() en una llamada a window.setTimeout() resuelve el problema. Retrasos de menos de 200 ms aún hacen que el problema ocurra.

No tuve que usar la solución de intentar encontrar si el atributo "length" existe en el documento [FlashId] objeto. Simplemente llamar a "FlashEmbed = document [FlashId]" funcionó bien.

+0

Interesante, tendré que intentarlo –

+2

lo siento @Robson - pero esta no es una buena idea. La condición de anticipación se debe a que el objeto SWF no se ha cargado y ejecutado y no se ha escrito la etiqueta en sí. La transferencia lenta de un archivo SWF puede demorar 10 segundos y es posible que nunca vea el problema en su equipo local porque no tendrá esas demoras en la red. Por favor, vea mi respuesta de la mejor manera (he encontrado) para llamar a Flash lo antes posible. –

+0

Creo que deberíamos poner un temporizador de repetición en Flash para comprobar si JavaScript está listo o no. –

13

Estoy de acuerdo con Robson en que es una condición de carrera, pero no está en 'escribir la etiqueta Flash' y agregar un temporizador no es una buena solución, de hecho es muy peligroso.

El problema es que el SWF en sí no está cargado y tuvo la oportunidad de inicializar su interfaz externa. Para un pequeño SWF en Chrome, el tiempo puede ser más sensible que otros navegadores, pero el problema subyacente no es específico de Chrome.

Lo que hay que hacer es esto:

en ActionScript

llamar a esta función de su constructor:

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

En su HTML

<script> 

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

</script> 

Puede encontrar en su máquina local que funciona sin esto, pero tan pronto como agregue demoras en la red en la ecuación se arrepentirá de no haberlo hecho. Un temporizador arbitrario es una mala idea porque aún recibirá el error en una conexión lenta. Este método permite que la página llame al objeto flash lo antes posible.


Nota: El uso de jQuery de 'lista de' patrón no es una solución al problema - aunque en un principio me confundí con uno.

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

también swfobject de callbackFn tampoco es una solución robaba eso le dice cuando se inserta la etiqueta y no cuando se carga el archivo SWF.

+0

gracias por la solución, incluso después de todo este tiempo. Después de un tiempo me di cuenta de que no era un problema específico de Chrome, sino que intentaba acelerar la devolución de llamada tal como lo mencionaste. Gracias por la solución también. – Mathias

+0

Hola Simmon, ¿qué quiere decir '$ ('# Main') [0] .activate();'? ¿Dónde está '# Main'? –

+1

activate() es solo el nombre de la función en la película flash que ha sido expuesta con ExternalInterface (hay una función activate() no mostrada aquí), y Main es la ID del swf como create by swfobject –

0

hay una solución al problema mediante la desactivación de Chrome incorporados plugin flash:

  1. tipo del chrome: // plugins en la barra de direcciones de Chrome.
  2. amplíe los detalles de los complementos haciendo clic en los detalles en la esquina superior derecha.
  3. en la entrada de "Adobe Flash Player", deshabilitando la primera.

Esto no es una solución, pero muestra por qué sucede esto en Chrome. Chrome lo acompaña con un plugin de flash incorporado, que a menudo causa problemas cuando usamos ExternalInterface de AS3, es molesto.

+0

A veces, los plugins integrados funcionan. Pero después de que Chrome se actualizó a una nueva versión (como la versión 28), el complemento integrado rompe las llamadas de ExternalInterface – zjy

Cuestiones relacionadas