"

  

  

EXECUTING JAVASCRIPT CODE FROM A FLASH MOVIE

  
One of the most interesting feature of Flash is the ability to communicate with JavaScript.  This article is intended to show how a Flash movie can "call" JavaScript functions.  
  

     

Quick Guide


This will be an example Flash movie that calls JavaScript code.  Below, you see a Flash movie with several buttons.  When user clicks a button, the Flash movie uses FSCommand to execute  JavaScript code.   (Your browser must be JavaScript enabled to see the example.  This has been tested with Internet Explorer 5 and Netscape  4.7 for the PC.  Netscape 6 or newer and Internet Explorer for the Mac might have problems running JavaScript calls.)

Creating the Flash Movie
Follow these steps:

  • Make a new movie.  

  • Make two buttons and put it on the screen like above.

  • Set the first button action to: 


Picture 1

  • Set the second button action to:


Picture 2

  • Pay attention to the Command parameter.  On the first button, it's set to "showMessageBox"; and on the second button it is set to "ask".  This parameter will be passed to JavaScript to tell JavaScript what to do.  

  • Save the movie as sampleFlaMovie.

  • Open the Publish Setting box (File->Publish Settings), then select  the HTML tab.  Set Template to "Flash with FSCommand" like shown below.


Picture 3

  • Publish the movie.

Creating the JavaScript

  • After publishing the movie, you should get a html page called sampleFlaMovie.html.  Open that file.

  • You should see some code generated by Flash.  In particular, pay attention to the <SCRIPT> section, which should look something like below:

<SCRIPT LANGUAGE=JavaScript>
<!--
var InternetExplorer = navigator.appName.indexOf("Microsoft") != -1;
// Handle all the the FSCommand messages in a Flash movie
function sampleFlaMovie_DoFSCommand(command, args) 
{
  var sampleFlaMovieObj = 
    InternetExplorer ? sampleFlaMovie : document.sampleFlaMovie;
  //
  // Place your code here...
  //
}
// Hook for Internet Explorer
if (navigator.appName && 
  navigator.appName.indexOf("Microsoft") != -1 &&
  navigator.userAgent.indexOf("Windows") != -1 && 
  navigator.userAgent.indexOf("Windows 3.1") == -1) 
{
  document.write('<SCRIPT LANGUAGE=VBScript\> \n');
  document.write('on error resume next \n');
  document.write(
    'Sub sampleFlaMovie_FSCommand(ByVal command, ByVal args)\n');
  document.write(
    ' call sampleFlaMovie_DoFSCommand(command, args)\n');
  document.write('end sub\n');
  document.write('</SCRIPT\> \n');
}
//-->
</SCRIPT>
  • Locate the place in that <SCRIPT> section where it says "// Place your code here".  That is the place where you should put additional/customized JavaScript code. 
  • For this example, create the "handler" for the two commands above: "showMessageBox" and "ask".  (These are arbitrary name, but should correspond to the Command parameter set on the Flash movie).  
<SCRIPT LANGUAGE=JavaScript>
<!--
var InternetExplorer = navigator.appName.indexOf("Microsoft") != -1;
// Handle all the the FSCommand messages in a Flash movie
function sampleFlaMovie_DoFSCommand(command, args) 
{
  var sampleFlaMovieObj = 
    InternetExplorer ? sampleFlaMovie : document.sampleFlaMovie;
  //
  // Place your code here...
  if (command == "showMessageBox")
    alert(args);
  if (command == "ask")
    prompt("How are you?", "Fine");
  //
}
// Hook for Internet Explorer
if (navigator.appName && 
  navigator.appName.indexOf("Microsoft") != -1 &&
  navigator.userAgent.indexOf("Windows") != -1 && 
  navigator.userAgent.indexOf("Windows 3.1") == -1) 
{
  document.write('<SCRIPT LANGUAGE=VBScript\> \n');
  document.write('on error resume next \n');
  document.write(
    'Sub sampleFlaMovie_FSCommand(ByVal command, ByVal args)\n');
  document.write(
    ' call sampleFlaMovie_DoFSCommand(command, args)\n');
  document.write('end sub\n');
  document.write('</SCRIPT\> \n');
}
//-->
</SCRIPT>

Making it work on Netscape

  • To make this work on Netscape browsers, a NAME tag must be present within the EMBED section.  I notice that on my Flash 4 version, this was not the case even when publishing with FS Command setting (see Picture 3).  A bug in the Flash template?  Whatever the case, it can be fixed like this.   
    Just open the html page, then find the place where it says 
    <EMBED ..... >.   If there's no name tag, then add it with
    NAME=sampleFlaMovie like below (you can use name= or NAME=, it is not case sensitive; but sampleFlaMovie must be typed as it is):  
<EMBED src="sampleFlaMovie.swf" NAME=sampleFlaMovie 
quality=high bgcolor=#FFFFFF WIDTH=200 HEIGHT=200 
....
</EMBED>

Note: every time you republish the Flash movie, the html page will be overwritten, and all modifications will be lost.  Therefore, it's recommended to save the modified html file with a different name.

Test the html page by opening in a browser (testing from Flash with TestMovie will not work).   If you understand what is going on (and everything works fine) at this point, then skip the next section.

How It Works


Flash has a built in mechanism to call JavaScript functions by using the FSCommand action.  There are several requirements for FSCommand to work: 

  • JavaScript must be enabled in the browser.  If not, then the FSCommand will fail (most likely it will do nothing).

  • Always specify both EMBED and OBJECT tags.  When putting the Flash movie inside a html page, use both tags.  This is because the OBJECT tag is only recognized by Netscape; and the EMBED tag is only recognized by Internet Explorer (as of version 4).  But wait, there are more specific requirements:

    • For OBJECT tag (IE):
      - ID must be present.  In the example, the ID is set by ID=sampleFlaMovie

    • For EMBED tag (NETSCAPE):
      - NAME tag must be present.   In the example, the NAME is set by NAME=sampleFlaMovie
      - SWLIVECONNECT=true must be present.  This tag is to "power-on" the ability to "connect" with the scripting language (e.q.: JavaScript).

    For example:

    <OBJECT 
      classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 
      codebase="" ID=sampleFlaMovie WIDTH=481 HEIGHT=86>
      <PARAM NAME=movie VALUE="theMovie.swf">
      <EMBED play=false name=sampleFlaMovie 
        src="theMovie.swf" swliveconnect=true 
        quality=high bgcolor=#FFFFFF 
        WIDTH=481 HEIGHT=86 
        TYPE="application/x-shockwave-flash">
      </EMBED>
    </OBJECT>

Note that the value of NAME and  ID are arbitrary, but they should be the same - this is to make your job easier.  Please use only alphabet characters or numbers (but don't start with a number), don't use punctuations.

If all of these seem confusing, remember that Flash can create the tags for you.  To do that, publish the movie with FS Command setting like below.

There is some problem in some versions of the Flash 4.  I don't know if this is a bug in the template or what, but for some reason, the NAME tag is omitted.  To fix it, publish using FS Command first, then find the place on the html page where it says <EMBED ..... > and add the name tag manually.  

  • A Flash movie must use a container function to execute  JavaScript codes.  What this means is that the Flash movie cannot call any arbitrary JavaScript functions "directly"  (unless, you use getURL() function).  Instead, you need to have a "container" function.  The Flash movie can then execute or call any other JavaScript function "through" the container function.  

    Think of the container function as a "middle-man".  A Flash movie must communicate with this some sort of a "middle-man" (sic) to interact with anyone else in the outside world.   Another way to conceptualize this is to think of the container function as a "gate".  A Flash movie must go through this "gate" to interact with the outside world.  (While this seems restrictive, it actually works well, and is a not a bad programming practice to have a single convergence point like this "gate/middle-man".  It will  make your code easier to maintain.)

For example.  Suppose you have a JavaScript function called "JSFunction", and you want to be able to call this function from Flash.  There are two things that you can do.  You can either a) make "JSFunction" the middle-man; or b) have the middle-man call "JSFunction".   

In choice a), the content of JSFunction is put directly inside the container function (this is similar to the example on the top of this page).  In choice b), here's what will happen: 

1. FlashMovie calls the Container function.
2. The Container function then calls JSfunction.

  • The "container" function must be named in this way.
function flashMovieName_DoFSCommand(command, args) 

where flashMovieName is the NAME or ID specified in the EMBED and OBJECT tags (this is why you should use the same value for both name and id).  In the example, since the movie's NAME and ID are set to "sampleFlaMovie", then the "container" function for that movie must be named:

function sampleFlaMovie_DoFSCommand(command, args)

Notice the underline character "_" between the movie name and "DoFSCommand."  This must be present.

If all of these seem confusing, again Flash can help.  When you use "Publish with FS Command" to publish your movie, Flash creates a template container function, and all you need to do is to add your own code inside the container function.   This feature should be used as the first step to make your job easier.  

  • The FS Command action takes two parameters: Command, and Arguments.  

    Don't worry about the pull down box shown on the bottom right.  It consists of predefined functions, which are only valid for standalone projector (these predefined functions won't have any effect if the movie is run from within a browser window).  

    The purpose of the Command parameter is to let JavaScript know what to do (this is required).  And the Arguments parameter is a place to put extra stuff (this is not required).  

  • If you have more than one Flash movie in a single html page, you must have a container function for each movie.  I.e.: you can't use one container function for more than one Flash movie; however, you can have the container function call another JavaScript function(s).  So, for example, if you have a JavaScript function named SharedFunction(), you can call this function from within each container function, thereby avoiding too much duplicate codes.

  • You can use FS Command as a frame action also.

Not working?


What to do if nothing seem to work?  Debugging is unpleasant, but here're some suggestions that might make it easier.  

  • Make sure both NAME and ID tag are specified.
  • Make sure the container function is named correctly (the prefix must match the NAME and ID).
  • Make sure JavaScript is enabled in the browser.
  • Make sure swliveconnect=true is specified in EMBED tag.
  • Avoid putting JavaScript code inside a TABLE, this may cause problem on some browsers.
  • Check for typo, movie NAME and ID must be prefixed in the the function correctly; the command argument in FS Command is case sensitive.
  • When testing, you must test the movie from a browser.  (Test Movie feature in Flash won't be able to execute JavaScript code.)
  • Every time you publish or republish a Flash movie, Flash will create a new html page with whatever name you specify in the PublishSettings.   If you modify that html page, you should save it with a different name.  This should help in avoiding accidental overwriting.  

Further Reading and Reference


More about this subject can be found in Flash 4 online help; check the "Creating Interactive Movies" topic, then select "Sending messages to the movie's host program" section.

JavaScript can also send data to a Flash movie; click here to read more.

<<INDEX>>

Terms of Use
  

(C) 2001 F. Permadi