Communication entre ActionScript 3 et JavaScript : ExternalInterface

Catégories : "Astuces", "Technologie" par Marouane Mighri Marouane Mighri le 14 Avril 2009

Communication entre ActionScript 3 et JavaScript : ExternalInterface

Le Web 2.0 s'oriente vers une forte interaction avec les utilisateurs ce qui donne une importance considérable à l'interface. Communiquer entre des composants permet de créer des applications riches en combinant les capacités et les limites de différentes technologies web.a

Par exemple, nous souhaitons insérer dans un formulaire HTML un calendrier pour choisir une date de façon plus esthétique et surtout plus simple pour l'utilisateur. Un composant Flex embarqué, comme DateChooser, pourrait faire l'affaire en synchronisant, bien évidement, le champ HTML correspondant avec l'application AS3.

Note : nous utiliserons Flex et Mootols pour illustrer cet exemple.

Quelques techniques existaient en Actionscript2, comme « fscommand() », pour gérer les appels Actionscript-JavaScript. Cette méthode était limitée par les différents navigateurs. De plus, elle ne permettait pas une communication synchrone entre les deux applications.

Elle était donc loin d'être idéale pour l'implémentation d'applications complexes. Désormais, Adobe recommande en AS3 l'utilisation de l'API ExternalInterface.

Note : la classe ExternalInterface nécessite la prise en charge, par le navigateur Web de l'utilisateur, d'ActiveX ou de l'API NPRuntime.

Plus généralement, à partir d'Actionscript ou de JavaScript, vous pouvez effectuer les opérations suivantes :

  • appeler des fonctions JavaScript depuis Actionscript, et inversement,
  • transmettre un nombre illimité de paramètres avec divers types de données,
  • synchroniser les deux applications en traitant la valeur retournée par l'une et l'autre.

Appeler une fonction JavaScript depuis Actionscript 3

Dans la classe flash.external.ExernalInterface, il existe deux méthodes : call et addCallback. Ces deux fonctions permettent une communication AS3 vers une application locale et inversement. La méthode call, comme son nom l'indique, va appeler une fonction JavaScript en indiquant le nom de la fonction et les paramètres qui lui seront passés.

Dans l'exemple suivant nous considérons une application Flex dans laquelle nous faisons appel à une fonction JS appelée receptionAppelAS3.

Le code suivant représente la fonction JavaScript qui sera appelée depuis l'application AS3:

var receptionAppelAS3 = function (message) { 
  alert('Réception de l\'appel AS3');
  return;
}

Le code AS3 contient une méthode appelJavascript() qui se charge d'appeler la fonction JavaScript extérieure en passant un seul paramètre qui est la date actuelle du système.

Nous considérons l'interface suivante contenant un composant Flex DateChooser et nous transmettons à JavaScript la date choisie par l'utilisateur.

flex 1Voici le code MXML pour l'interface ainsi que la fonction d'initialisation :

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
  layout="absolute" creationComplete="init()" &nbsp;
  borderColor="#F31E73" themeColor="#FF0054"
  backgroundGradientAlphas="[1.0, 1.0]"
  backgroundGradientColors="[#767273, #767273]" width="291" height="267">
 
  <mx:DateChooser horizontalCenter="0" top="10" id="calendar"/>
 
</mx:Application>

Et voici le code Actionscript 3 associé :

import mx.formatters.DateFormatter;
import mx.controls.Alert;
 
// initialisation de l'application
public function init():void {
  // ajout d'un Listener sur l'évènement et appel de la fonction javascript
  calendar.addEventListener(MouseEvent.CLICK, appelJavascript);
 
  // interception de l'évènement reçu depuis Javascript
  // et appel de la fonction Callback de traitement
  ExternalInterface.addCallback("appelAS3", receptionAppelJavascript);
}
 
// appel de la fonction Javascript
public function appelJavascript(ev:MouseEvent):void {
  // appel de la fonction Javascript permettant de changer la date
  ExternalInterface.call('receptionAppelAS3', selectedDay,tosString());
}
 
// traitement de l'appel reçu depuis Javascript
public function receptionAppelJavascript(str:String):Boolean {
  // affichage du message reçu depuis l'appel Javascript
  Alert.show(str);
  return true;
}

L'appel de la fonction init() est fait à l'initialisation de l'application : « creationComplete=init() ». On l'utilise donc pour ajouter un Listener sur l'événement Click du calendrier.

Il suffit maintenant d'intégrer le fichier flash dans la page HTML pour voir le résultat. Un clic sur le composant Flex invoque la fonction receptionAppelAS3() de JavaScript et donne le résultat suivant :

flex2
Le résultat renvoyé par le composant DateChooser peut être filtré pour retourner la date sous un format standard « YYY-MM-DD ». Nous ajoutons les modifications suivantes à la méthode appelJavascript :

// appel de la fonction Javascript
public function appelJavascript(ev:MouseEvent):void {
  var selectedDay:Date = calendar.selectedDate;
  var dateFormat:DateFormatter = new DateFormatter();
 
  dateFormat.formatString = "YYYY-MM-DD";
 
  // appel de la fonction Javascript permettant de changer la date
  ExternalInterface.call( 'receptionAppelAS3', dateFormat.format(selectedDay) );
}

Nous obtenons le message suivant à l'exécution :

flex3
Nous pouvons maintenant utiliser ce résultat dans un champ de texte qui représente la date :

<input type="text" id="date" />

La fonction JavaScript appelée :

var receptionAppelAS3 = function (message) {
  alert('Reception de l\'appel AS3');
 
  // modification du champ date
  $("date").value = message;
  return;
}

La méthode call() fonctionne aussi de manière synchrone. Par exemple, la fonction JavaScript appelJavascript() pourrait mettre l'application en pause jusqu'à ce que l'utilisateur clique sur un bouton et retourne true pour un clic sur OK ou false pour un click sur Cancel.

L'exemple suivant illustre cette synchronisation :

var option:Boolean = ExternalInterface.call(
  "receptionAppelAS3",
  "Appuyer sur OK pour continuer !"
);

Appeler une fonction Actionscript 3 depuis JavaScript

L'appel d'une fonction AS3 est aussi possible à partir d'une application JavaScript. Il faut simplement déclarer le nom des fonctions qui seront appelées en leur donnant des alias ainsi que le nom de la fonction AS3 interne qui sera exécutée au moment de l'appel. Pour se faire, on utilise la méthode ExternalInterface.addCallback.

Dans le code suivant, l'application AS3 exécute la fonction receptionAppelJavascript chaque fois qu'il y a un appel JavaScript externe appelAS3 :

import flash.external.ExternalInterface;
 
// interception de l'évènement reçu depuis Javascript
// et appel de la fonction Callback de traitement
ExternalInterface.addCallback("appelAS3", receptionAppelJavascript);
 
// traitement de l'appel reçu depuis Javascript
public function receptionAppelJavascript(str:String):Boolean {
  // affichage du message reçu depuis l'appel Javascript
  Alert.show(str);
  return true;
}

Considérons que le code AS3 est compilé dans un fichier swf nomme flex.swf.

Le code JavaScript doit contenir une fonction permettant de récupérer l'objet Flash ainsi qu'une fonction pour faire appel à la méthode extérieure.

Pour remédier aux problèmes d'exceptions des navigateurs plusieurs solutions sont proposées. Nous utiliserons ici la bibliothèque Mootools avec l'extension Swiff.

Dans ce cas le code ressemblera à :

window.addEvent('domready', function() { 
 
  // création de l'objet flash à l'aide de Swiff
  var flashObject = new Swiff('Flash.swf', {
    width: '300',
    height: '200',
    id : 'flashObject',
    params: {
      align: 'middle',
      allowScriptAccess: 'always',
      play: 'true',
      pluginspage: 'http://www.adobe.com/go/getflashplayer',
      quality: 'high'
    }
  });
 
  // remplacement de l'objet HTML par l'objet flash
  // qui vient d'être instancié
  flashObject.replaces($('flashObjectContainer'));
 
  // ajout d'un évènement sur le bouton
  $('bouton').addEvent('click', function() {
    appelAS3();
    return;
  });
 
});
 
// appel de la fonction AS3
var appelAS3 = function () {
  // envoi de l'évènement vers l'objet AS3
  // avec le nom de la fonction à lancer
  Swiff.remote($('flashObject'), "appelAS3", $("date").value);
}

La classe Swiff permet de générer un objet flash et ensuite de le placer dans la page HTML. La méthode remote de Swiff permet d'invoquer la fonction AS3 nommée appelAS3 avec un passage de paramètre.

C'est terminé ! Nous venons de réaliser une communication bidirectionnelle via Externalinterface. L'implémentation est donc très souple et permet de faire communiquer des applications JavaScript et Actionscript et même des applications Actionscript entre elles.

Les sources de cet exemple sont disponibles ci-dessous. Cet exemple nécessite un serveur web pour être exécuté (wampserver, etc...), il ne fonctionnera pas en local.
Exemple pratique

Exemple pratique

exemple-interaction-as3-javascript.zip 318,65 kB

 

Communication entre ActionScript 3 et JavaScript : ExternalInterface

A propos

Bienvenue sur le Workshop de l'agence interactive Maecia : notre espace d'actualités, de veille et de publications sur les nouvelles tendances d'Internet. Vous y trouverez aussi le fruit de certains de nos développements techniques que nous mettons à disposition de la communauté. Découvrez notre vision du web et surtout n'hésitez pas à prendre la parole !