ActionScript: Comunicacion este Javascript y Flash (ExternalInterface vs fsCommand)

Un amigo diseñador grafico necesitaba comunicar desde una funcion JS hacia Flash, y aquí mi respuesta, pero quise dejar sentado como era (hace un tiempo con versiones anteriores) y hoy con la nueva ExternalInterface.
Sobre una pregunta que me dio nostalgia, ya que hace un par de años dictaba cursos de Flash/Dreamweaver/ASP Clasico (etc, etc) (hay que ganarse la vida), y hoy por falta de tiempo (y de ofrecimientos) solo damos cursos de NET 🙂
Pero por que escribo por aqui sobre esto? Porque con ExternalInterface es al manera actual de comunicarse entre Flash y algun contenedor como un winform en .NET si queremos embeberlo, cuando tenga algun tiempo libre escribire sobre ello, aunque con el potencial de WPF ya no lo deseemos. 
Sincrona? Porque podriamos comunicarnos con Flash mediante Webservices, pero eso tambien es otro tema 🙂

 

UPDATE: 01/10/2008 (testado en IE7, FF3, Chrome, Safari) 
Gracias al comentario de Rover que detecto que en Firefox (3.0) no funcionaba, y alli tambien lo teste en Chrome y tampoco se comunicaba desde JS hacia Flash.
Problema:
       Esta linea

var flashObject = document.getElementById('ExternalInterfaceDEMO');

No detectaba/encontraba el objecto en el DOM de la pagina

Como utilizaba AC_RunActiveContent.js (el script de Adobe para el antiguo problema de IE que bloqueaba los activex en las paginas objecto object/embed)

Solucion:

Utilizar el conocido SWFObject.js

Para hacerlo simplemente hay que descargarse el script y linkearlo en nuestra pagina   

<script type="text/javascript" src="/js/SWFObject/swfobject.js"><!--     // //--></script> 

Luego para insertar la pelicula hay que realizar

<script type="text/javascript">
   1:  
   2:     var flashvars = {};   
   3:     var params = {};
   4:     params.wmode = "transparent";
   5:     params.bgcolor = "#FFFFFF";
   6:     var attributes = {};
   7:     swfobject.embedSWF("ExternalInterfaceDEMO.swf", "ExternalInterfaceDEMO", "550", "400", "8", "/js/swfobject/expressInstall.swf", flashvars, params, attributes);
   8:    

</script>

<div id="ExternalInterfaceDEMO">
<strong>Ud. necesita actualizar su reproductor de Flash</strong>
<a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Descargar Adobe Flash Player" /></a>
</div>

Como pueden ver el contenedor tiene el ID “ExternalIntefaceDEMO”, y es el que tomara el obejecto incrustado y alli su funcionara

var flashObject = document.getElementById('ExternalInterfaceDEMO');


Esta actualizado el archivo para la descarga.

 

 

Un poco de historia…

Hasta Flash 7 la forma de comunicación entre Flash —> Javascript era con el simple getURL y/o fsCommand (todo esto es Actionscript)… en este ultimo para probar habia que acordarse de cambiar algunas cosas.

Para la comunicacion entre Javascript —> Flash era con SetVariable (una ardua tarea, creanme)


Ejemplo:

getURL('j a v a s c r i p t:miFuncionJS('+mensaje+')');

tambien…
fscommand('miFuncionJS', mensaje);

No viene al caso ver como hacer funcionar estas dos ejemplos.. ya que mi comentario es sobre ExternalInterface.

 

Utilizando ExternalInterface

 

  • Flash –> Javascript

En la pelicula tendriamos algo asi (a modo de ejemplo) llamamos a un funcion desde Actionscript hacia Javascript llamada Mensaje

Antes que nada importamos la clase: flash.external.ExternalInterface

 image

En la pagina HTML tenemos

<script type="text/javascript" language="javascript">
    function Mensaje(texto) {
        var txtMensajeHTML = document.getElementById('txtMensajeHTML');
        txtMensajeHTML.value = texto;
    }
</script>

Desde Flash llamamos a la funcion en en el click (release) del boton.

Si quieres puedes descargar el ejemplo (ver mas abajo)

image


  • Javascript –> Flash

En el mismo ejemplo…vamos a comunicarnos desde js hacia flash. Aqui en Javascript tenemos:

function ParaFlash(msj){
        var flashObject = document.getElementById('ExternalInterfaceDEMO');
        if (flashObject != null) {
            flashObject.MensajeHaciaFlash(msj);
        }        else {
            alert("Error. No se ha podido comunicar con Flash. Verifique");
        }
    }
Por si estas mirando el codigo de arriba veras que accesamos al ID de la pelicula flash, es decir “debe tener un ID”

El id del tag object debe ser el mismo que el name del tag embebed  Actualizacion: Ahora utilice SWFObject (Ver mas arriba)

image
Idem si utilizamos SWFObject o AC_RunActiveContent que nos ayudan a escribir la pelicula en nuestras paginas. A tenerlo en cuenta

Actualizacion: Ahora utilice SWFObject (Ver mas arriba)

 

En ActionScript

image

en el HTML llamamos a la funcion:

<textarea id="txtMensajeHTML" cols="40" name="S1" rows="6"></textarea>
<br />        
<input id="btnVerMensajeParaFlash" type="button" value="Mensaje Hacia Flash" 
   onclick="ParaFlash(txtMensajeHTML.value);"  /></p>

 

 

 

NOTA: Esto se testea en un servidor web, no pruebes de forma local, para hacerlo de forma local deberias cambiar el parametro allowScriptAccess al valor “always” (por razones de seguridad). Pero tambien deberias configurar tu reproductor flash (ver video).

<param name="allowScriptAccess" value="sameDomain" />

Por

<param name="allowScriptAccess" value="always" />

Tambien configurar el reproductor (ver video)

 

 

Limitaciones para utililizar ExternalInterface

ExternalInterface funciona en:

  • Version de Flash 8 o superior…
  • Navegadores como:

    Windows Internet Explorer 5.0 o superior,

    Firefox 1.0 o superior

    Mozilla 1.7.5 o superior

    Netscape 8.0 o superior

    Safari 1.3 o superior.

    Opera 9 o superior.

    y cualquier broser que soporte NPRuntime API
  • Puedes preguntar si esta disponible para utilizar con la propiedad ExternalInterface.available

 

Lo testee en IE7, FF3, Chrome y Safari

 
image

 

Descargar ejemplo

Actualizada al 01/10/2008: con SWFObject

 

Que tiene esta interfaz sencilla donde podras enviar tanto desde flash hacia js como desde js hacia flash un texto.

image

 

 

UPDATE: 01/10/2008

Como Flash cuando arma el HTML para testear la pelicula lo realiza con el script AC_RunActiveContent.js, que era la solucion de Adobe para el problema del bendito IE que bloqueaba los objectos object/embeb

Mas arriba ya explique el problema y la solucion con SWFObject

<script language="javascript" type="text/javascript">
    if (AC_FL_RunContent == 0) {
        alert("This page requires AC_RunActiveContent.js.");
    } else {
        AC_FL_RunContent(
            'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0',
            'width', '550',
            'height', '400',
            'src', 'ExternalInterfaceDEMO',
            'quality', 'high',
            'pluginspage', 'http://www.macromedia.com/go/getflashplayer',
            'align', 'middle',
            'play', 'true',
            'loop', 'true',
            'scale', 'showall',
            'wmode', 'window',
            'devicefont', 'false',
            'id', 'ExternalInterfaceDEMO',
            'bgcolor', '#ffffff',
            'name', 'ExternalInterfaceDEMO',
            'menu', 'true',
            'allowFullScreen', 'false',
            'allowScriptAccess', 'sameDomain',
            'movie', 'ExternalInterfaceDEMO',
            'salign', ''
            ); //end AC code
    }
</script>

 

 

 

Enlaces

15 comentarios en “ActionScript: Comunicacion este Javascript y Flash (ExternalInterface vs fsCommand)”

  1. Hola rover
    Efectivamente no funcionaba en FF3, era por un problema de como renderizaba el script AC_RunActiveContent.js, ahora lo cambie por SWFObject (no me preguntes porque no lo hice desde un principio je!)
    YA modifique el articulo.

  2. yo hice una pagian web en html, en la parte superior coloque un flash con botones y algunas animaciones, y en la parte inferior de la pag hay unas tablitas con info, etc, yo quiero hacer que cuando presione uno de los botones del flash me envie hasta el final de esa pagina html, (OSEA COMO SI PRESIONARA LA TECLA END DEL TECLADO PERO DESDE UN SIMPLE CLICK CON EL MOUSE SOBRE EL BOPTON) pero no se como, he provado una y mil maneras pero nada, agradeceria si me ayudaran

  3. Hola, acabo de bajar el ejemplo, puesto en mi servidor web y la pelicula flash no aparece.
    Obtengo un error en la línea 57. El objeto swfobject no esta definido.

    ¿A qué puede deberse?

    Muchas gracias, un saludo.

  4. hola, buenas tardes, descargue el ejemplo pero no me funciona en firefox 3.0.5, si me funciona con internet explorer, y estoy utilizando SWFObject
    Gracias…

  5. @Jose Luis Barona
    Como estas? como estas probando el ejemplo?
    No funciona si lo ejecutas directamente sino a traves de un servidor web.
    Si puedes testea en un servidor en tu maquina y abrelo con FF

  6. El ejemplo es genial me funciono bien en los navegadores. el problema lo tengo porque uso greybox , en el iframe que cargo tengo esta accion:
    parent.parent.ParaFlash(mitexto); para comunicarme con flash, uso paren porque estoy fuera de la pagina raiz.

    El caso este se ejecuta genial en firefox y safari pero en IE no funciona y me aparece un error en el navegador que dice “El objeto no acepta la propiedad o metodo” y corresponde a esta linea donde tengo alojado el flash : flashObject.MensajeHaciaFlash(msj);

  7. queria consultar los siguiente:

    cuento con una pagina que contiene un iframe y dentro del iframe se encuentra el swf.

    necesito hacer una llamada desde el swf al javascript del documento principal y que este le entregue a flash una respuesta.

    suena complicado y queria saber si es posible hacerlo.

    gracias por la respuesta, slds.
    webmaster@sgwd.com.ar

  8. Hola @Sergio
    Si se puede.
    En el articulo solo explico la comunicacion de Flash <> Javascript

    La forma de comunicarte con el padre de un iframe seria:
    1) Desde el iframe con el objeto parent:
    parent.document.miFuncion();
    2) Desde la ventana padre del iframe, puedes utilizar el objeto window.frames u obtener el iframe buscandolo por id
    Me gusta mas el ultimo
    document.getElementById(‘elNombreDelIframe’).contentWindow.miFuncionDentroDelIframe();

    en base a esto puedes escribir el codigo para llamar dentro del Flash a una funcion javascript dentro de la pagina (del iframe) y desde dicha funcion recien llamar a la funcion de la pagina padre.
    (que trabalenguas)

    Espero que te sirva de ayuda o guia.

  9. Hola, estoy armando la web del estudio a donde trabajo, sé muy poco de programación. La armé con css. El problema que tiene es que se vé bien en casi todos los monitores (resoluciones) pero en algunas me tira el error “swobject no está definido”. Y entonces lo que pasa es que el div “contenido” se sitúa debajo de la botonera…
    Cómo debería hacer para solucionarlo? sirve el código explicado arriba? GRACIAS por tu pronta respuesta!!!

    [ Te agradecería mucho copiarme la respuesta también a dg.gaby@hotmail.com.ar ]

  10. Hola @Gabriela
    El error es porque no se encuentra el objeto “swobject” porque no esta bien definido el archivo .js donde esta implementado
    En tu pagina tienes algo asi?

    Tienes eso, que busca desde el raiz “/js..” mira la carpeta… donde quiere encontrar el archivo .js si es correcta dependiendo de donde esta la pagina

    NOTA 1: Utiliza un visualizador tipo Firebug para ver errores y depurar tu pagina web directamente desde tu navegador. en IE ya viene includo

    NOTA 2: Este post esta en um blog personal, no puedo respondar rapidamente, asi que date una vuelta por el Foro de Desarrollo en ASP.NET que te podremos ayudar mejor
    http://social.msdn.microsoft.com/Forums/es-ES/netfxwebes/threads

    Saludos

  11. Hola. Estoy armando un sitio que tiene varios estilos CSS que cambian dinámicamente mediante Javascript. Cada estilo de página lleva un reproductor Flash de MP3, pero no logro llamar a los reproductores desde Javascript, para que cambien junto con cada estilo (supongo que debería agregar alguna variable al mismo código que uso para hacer los cambios de estilo, pero no sé cuál es) Si pudieras darme una mano con el código necesario me harías un gran favor y quedaría muy agradecido (ya hace meses que estoy trabado con esto) El sitio en construcción es http://www.oscuriclaros.com.ar (preferiría que no apareciera la dirección del sitio en este comentario) Perdón si no estoy escribiendo en el apartado correspondiente.

    Repito para que se entienda: Cada estilo CSS lleva un reproductor Flash con colores de fondo y colores de botones diferentes (o sea, tengo 12 estilos y 12 reproductores Flash hechos, que en realidad son 24 y 24: los otros 12 y 12 son los mismos pero en otro tamaño) Lo que necesitaría es llamar desde Javascript al reproductor correspondiente a cada estilo (lo de cargar los MP3 en los reproductores lo tengo resuelto, y no me importa si al cambiar de páginas las grabaciones se cortan)

    Gracias, y saludos…

    Diego

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *