Knowing When It’s Safe To Talk To Flash From JavaScript

I’ve been doing some work lately where JavaScript in an XHTML page needs to talk to some ActionScript 3.0 in a Flash movie.

The most common problem here is knowing when you can start talking to the Flash movie. The browser may have loaded all the scripts and started to execute them, but the flash movie may not have loaded or initialised at that point. If you try to talk to the movie at this point, you’ll get errors.

There are a couple of ways around this. You could code the flash movie into the page using <object> and <embed> html tags, then make sure your JavaScript calls the movie after the onload event has been called. E.g.

function flashLoaded() {
alert("Flash loaded");
}
window.onload = function() {
// flash should have loaded by now.
flashLoaded();
}

Now that isn’t ideal, the flash may have loaded, but the movie may not have initialised so you could still have problems.

The safest way is to include a callback function in your ActionScript that runs once the movie has finished initialising. This will call some JavaScript on your page letting you know the movie has loaded and can be interacted with. We can use the ExternalInterface class in the ActionsScript to achieve this.

Let’s assume our ActionScript class is called test, and we have a function in our JavaScript called flashLoaded. The following code is a quick way to let the JavaScript know the movie has loaded.

public function test():void
{
ExternalInterface.call("flashLoaded");
}

This is great, but it does mean we’ve had to hardcode the name of the calling function. What if we had two Flash movies in the page and they both called this function. This could cause problems. We need a way to pass in a function name dynamically.

Flash has something that used to be called FlashVars that can help us here. It’s basically a list of parameters and values that are passed and appended as a query string to the end of the movie files name. These are then available to ActionScript. In our object we alter the movie paramter accordingly.

<-- in the flash object tag -->
<param name="movie" value="test.swf?onLoad=flashLoaded" />

If you use the embed tag, make sure you alter the movie parameter there as well.

To see the passed parameters in ActionScript was need to use root.loaderInfo.parameters. Our initialiser function should be altered to use the following code, in this case we want to use the onLoad parameter.

public function test():void
{
ExternalInterface.call(root.loaderInfo.parameters.onLoad);
}

Great, we can now vary our the name of our callback. However problems could still occur. The movie may be loaded but the stage may not be ready. We need to add a little bit more wrapping code to handle this. The following code should do the trick.


package {
import flash.display.Sprite;
import flash.events.*;
import flash.external.ExternalInterface;
public class test extends Sprite
{
public function test():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
ExternalInterface.call(root.loaderInfo.parameters.onLoad);
}
}
}

As you can see we’ve moved the callback into the init function, and this is only called when the stage is ready.

You should now be safely able to script your flash movie from JavaScript.

See Knowing When It’s Safe To Talk To Flash From JavaScript – Part 2 for examples on how to integrate this with a modern JavaScript library like jQuery.

One thought on “Knowing When It’s Safe To Talk To Flash From JavaScript”

Comments are closed.