Quick start with Flash ExternalInterface class

The ExternalInterface class allows you to communicate with the Flash wrapping container, which is usually the HTML page with JavaScript capeability. It allows you to send data from ActionsScript to JavaScript and vice versa.

The ExternalInterface class is implemented for nearly all current browsers. Please see the documentation for a detailed list of the supported browsers here.

All five attributes and methods are static, so you don’t need an instance of this class.

Make sure ExternalInterface is available

When using the ExternalInterface you should make sure it’s available. So please test the boolean value ExternalInterface.available:

if( ExternalInterface.available ){
  ExternalInterface.call( .... )
}

Call JavaScript from ActionScript

To call a JavaScript function from ActionScript you just the the method ExternalInterface.call. First argument must be the function name of the JavaScript method you would like to call. All other parameters will hand over as parameters to the JavaScript method. These parameters should be primitive types like String, Number or even simple Object.

JavaScript:

function myJSFunction( param1, param2, param3 ){
   alert( param1 + ': ' + ( parseInt(param2,10) + parseInt(param3,10) ) );
   // parseInt is definetly the nicer way
}

ActionScript:

private function externalInterfaceTest():void{
   var a:int = 4;
   var b:int = 2;
   var c:String = "Hello World";
 
   ExternalInterface.call( "myJSFunction", c, b, a );
}

This will show up an alert window with text and calculated numbers.

The call method will also handle return values of the JavaScript method. At least for this you should be aware of the security model of the flash player, otherwise you might get an null value instead the expected result. Therefore please set the flash parameter allowScriptAccess to always and the allowed domain within your flash application.

HTML:

<param name="allowScriptAccess" value="always" />
   <embed allowScriptAccess="sameDomain" [...]

SWFObject:

var params = {};
   params.allowscriptaccess = "always";
swfobject.embedSWF("flvplayer.swf", "videoPlayer", "650", "530", "9.0.28", "expressInstall.swf", flashvars, params, attributes);

Flash App:

flash.system.Security.allowDomain( yourDomain );

If you configured that way you will be able to recieve return values from your JavaScript function and use them in your ActionScript method.

JavaScript:

function myJSFunction( val ){
   return "JavaScripts says: " + val;
}

ActionScript:

private function exInterfaceTest():void{
   if( ExternalInterface.available ){
      trace( ExternalInterface.call( "myJSFunction", "Hello World") );
   }
}

Call ActionScript method from JavaScript

Its also possible to start the other way round, that you call an ActionScript method from an JavaScript function. Therefor you have to register an callback function within your AS code. You will connect any method name with an existing method.

This is done with the addCallback method. First argument is any function name you like. This will be the function you could call within JavaScript. The second argument is an function reference or closure which should be handle the call. All arguments will be passed to this method.

The JavaScript side function is an object of the flash wrapping container ( Object-Element / Embed-Element ) which should be referenced by it’s id/name. Also for this direction arguments and return values are possible.

HTML/JavaScript:

 <script language="JavaScript">
     var init = false;
     var flashObjId = "myExInterfaceTest";
 
     // flash is initialised and AS methods could be called
     function flashReady(){
         init = true;
         callAsMethod();
     }
 
     function callAsMethod() {
         var objRef;
 
         if ( window[ flashObjId ] ) {
             // none microsoft
             objRef = window[flashObjId];
         } else {
             objRef = document[flashObjId];
         }
 
         alert( objRef.jsCallHandler( "myArguments" ) );
     }
 </script>
 </head>
 <body>
     <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
             id="myExInterfaceTest" width="100" height="100"
             codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
         <param name="movie" value="test.swf" />
         <param name="allowScriptAccess" value="sameDomain" />
         <embed src="test.swf" quality="high"
             width="100" height="100" name="myExInterfaceTest" align="middle"
             allowScriptAccess="sameDomain" pluginspage="http://www.macromedia.com/go/getflashplayer_de">
         </embed>
     </object>
 
 </body>

ActionScript part:

// This method is called when initialisation is finished and application is ready
private function initCompleteHandler():void{
   if( ExternalInterface.available ){
       ExternalInterface.addCallback( "jsCallHandler", javaScriptHandlerMethod );
       ExternalInterface.call( "flashReady" );
   }
}
 
private function javaScriptHandlerMethod( arg ):Boolean{
    return ( "ActionScript says:" + arg );
}

For a large number of JavaScript calls from ActionScript to JavaScript i regular use the jsCallStack class which implements an stack of javascript calls to handle this timed and avoid doubled calls.