Quick Tip: How to Communicate Between Flash and JavaScript

Quick Tip: How to Communicate Between Flash and JavaScript

Tutorial Details
  • Difficulty: Intermediate
  • Program: Flash
  • Technologies: ActionScript 3.0, Javascript

In this Quick Tip, we’ll look at how to use the ExternalInterface class. This allows us to write AS3 which can run JavaScript code, and vice-versa. That means you can use Flash to alter parts of the webpage in which it’s running!


Step 1: Set up the Flash Document

Create a new Flash ActionScript 3 document. Resize the stage to be 600×300. With the rectangle tool, draw out a rectangle that is the size of the stage. Give it a color of #CCCCCC. Also, give it a black stroke of 2px.


Step 2: Set up the Flash UI

Here’s the layout we’ll be working towards:

Open the Components Panel (Window > Components) and, from the User Interface folder, drag a ColorPicker component onto the stage. Give it an instance name of ‘cp’.

Next create a dynamic text field called ‘resizeText’; place and size it however you please (you can’t see the one in my image; it’s empty, and in the top-right of the stage.)

Now, create another dynamic text field. Give it an instance name of ‘jsText’. Then create a button symbol and give it an instance name of ‘prompt’. After that, create another button and give it an instance name of ‘change’.

Finally, create two input text fields. Place one next to your ‘prompt’ button, and give it a name of ‘promptText’. Take the second text field, move it next to your ‘change’ button and name it ‘changeText’.

Also, add any labels you want; refer to my image to see how I set it up.


Step 3: Set up the HTML UI

In order for the ExternalInterface to work, the document has to be on the internet. First, create a new text file, and save it as ‘externalInterface.html’. Next, open a text editor and add all the code below. Save the HTML file.

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>externalInterface</title>
<style type="text/css">

body {
	font-family:Arial;
}

#asSend {
	padding-top:20px;
	font-size:12px;
}
#htmlWrap {
	margin-top:10px;
	width:578px;
	padding-left:20px;
	border-width:1px;
	border-style:solid;
}
#sender {
	margin-top:10px;
}
#textChange {
	font-size:13px;
	font-weight:bold;
	padding-top:10px;
	padding-bottom:20px;
}

</style>
</head>
<body>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="600" height="300" id="externalInterface" align="middle">
  <param name="allowScriptAccess" value="sameDomain" />
  <param name="allowFullScreen" value="false" />
  <param name="movie" value="externalInterface.swf" />
  <param name="quality" value="high" />
  <param name="bgcolor" value="#ffffff" />
  <embed src="externalInterface.swf" quality="high" bgcolor="#ffffff" width="600" height="300" name="externalInterface" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
<div id="htmlWrap">
<div id="asSend">
  <label for="textArea">Send to actionscript:</label><br />
  <textarea cols="50" rows="4" id="textArea" name="textArea"></textarea>
  <br />
  <button id="sender" name="sender">Send</button>
</div>
<div id="textChange">Use Actionscript to change me!</div>
</div>
</body>
</html>

The key areas are:

  • The <object> section, which embeds the SWF you’ll create from the Flash file.
  • The <div>s and <textarea>, which have id properties so that we can access them from the SWF.

Your HTML should appear as below:

When the code has been replaced, upload the file to your webserver, so we can get started with the ActionScript.


Step 4: Set up a Document Class

Create a document class for your Flash file; call it Main.as. If you’re not familiar with document classes, read this Quick Tip.

package
{
	import flash.display.MovieClip;
	public class Main extends MovieClip {
		public function Main() {

		}
	}
}

Step 5: Calling JavaScript Functions from Flash

The first thing we’ll do with the ExternalInterface is call a JavaScript function that will change the background color of our webpage. So, attach an event listener to our ColorPicker component. When the color changes, it will send the hex value to a javascript function called receiveColor():

package
{
	import fl.events.ColorPickerEvent;
	import flash.display.MovieClip;
	public class Main extends MovieClip {
		public function Main() {
			cp.addEventListener(ColorPickerEvent.CHANGE, colorChange);
		}

		public function colorChange(event:ColorPickerEvent):void {
			ExternalInterface.call("receiveColor", event.target.hexValue);	//calls receiveColor(event.target.hexValue) in the javascript
		}
	}
}

Now we have to write this receiveColor() function. In the head of our HTML document, we start the javascript by defining this function. It simply takes the value sent to it from Flash and changes the background color.


Put that right after <head> in your HTML file. If all’s well, when you run the HTML page in a browser and change the color in the ColorPicker, it should change the background color of the webpage.


Step 6: Calling ActionScript Functions from JavaScript

The next example will be to send data from JavaScript to Flash. In the HTML document, paste the following code within the <script> tag you added in the last step:

window.onload = function() {
	var sender = document.getElementById("sender");		//getElementById finds an element according to its "id" property
	sender.onclick = function() {
		var ta = document.getElementById("textArea");
		document['externalInterface'].receiveText(ta.value);
		ta.value = "";
	};
};

Here’s what this does: after the document is loaded, we get the ‘sender’ button and attach an event listener to it. When the ‘sender’ button is clicked, it will call the receiveText() function in Flash that we will set up now.

Back in Flash, we tell the ExteralInterface to register the ActionScript function so that it can be called from JavaScript. Then we set up our receiveText() function:

package
{
	import fl.events.ColorPickerEvent;
	import flash.display.MovieClip;
	public class Main extends MovieClip {
		public function Main() {
			cp.addEventListener(ColorPickerEvent.CHANGE, colorChange);
			ExternalInterface.addCallback("receiveText", receiveText);	//allows JavaScript to access the receiveText() function.
		}

		public function colorChange(event:ColorPickerEvent):void {
			ExternalInterface.call("receiveColor", event.target.hexValue);
		}

		//this is the new receiveText function
		public function receiveText(value:String):void {
			jsText.text = value;
		}
	}
}

(New lines are 8 and 15-18.)


Step 7: Calling JavaScript Alerts, Confirms and Prompts from ActionScript

We can also call alerts very easily from ActionScript. Here we simply tell the ExternalInterface to call a ‘prompt’. We can also use the ExternalInterface to pass parameters to functions. Here we tell the ‘prompt’ function to ask the user his or her name. When our user enters the info, it’s passed back to the ‘promptText’ text field.

package
{
	import fl.events.ColorPickerEvent;
	import flash.display.MovieClip;
	public class Main extends MovieClip {
		public function Main() {
			cp.addEventListener(ColorPickerEvent.CHANGE, colorChange);
			ExternalInterface.addCallback("receiveText", receiveText);
			prompt.addEventListener(MouseEvent.CLICK, promptClick);	//makes promptClick() run when prompt button is clicked
		}

		public function colorChange(event:ColorPickerEvent):void {
			ExternalInterface.call("receiveColor", event.target.hexValue);
		}

		public function receiveText(value:String):void {
			jsText.text = value;
		}

		//function to be called when prompt button is clicked. Will ask for user's name using a JS prompt.
		public function promptClick(event:MouseEvent):void {
			promptText.text = "You said your name is: " + ExternalInterface.call("prompt", "What is your name?");
		}
	}
}

(New lines are 9 and 20-23.)


Step 8: Calling Anonymous JavaScript Functions

Another thing we can do is write our own JavaScript functions as strings, then call them from the ExternalInterface. Here we create a JavaScript function that receives a parameter. We take that parameter and assign its value to the innerHTML attribute of our ‘textChange’ div in the HTML document. You’ll notice that there are no external JavaScript functions being called – it is all contained within the ActionScript.

package
{
	import fl.events.ColorPickerEvent;
	import flash.display.MovieClip;
	public class Main extends MovieClip {
		public function Main() {
			cp.addEventListener(ColorPickerEvent.CHANGE, colorChange);
			ExternalInterface.addCallback("receiveText", receiveText);
			prompt.addEventListener(MouseEvent.CLICK, promptClick);
			change.addEventListener(MouseEvent.CLICK, changeClick);	//makes changeClick() run when change button is clicked
		}

		public function colorChange(event:ColorPickerEvent):void {
			ExternalInterface.call("receiveColor", event.target.hexValue);
		}

		public function receiveText(value:String):void {
			jsText.text = value;
		}

		public function promptClick(event:MouseEvent):void {
			promptText.text = "You said your name is: " + ExternalInterface.call("prompt", "What is your name?");
		}

		//changes text inside the HTML to match text field inside Flash
		public function changeClick(event:MouseEvent):void {
			ExternalInterface.call("function(param){ document.getElementById('textChange').innerHTML = param; }", changeText.text);
			changeText.text = "";
		}
	}
}

(New lines are 10 and 25-29.)


Step 9: Calling Anonymous JavaScript and ActionScript Functions

Finally, we can call anonymous functions on both sides. In the ‘anonymous’ function, we register an anonymous ActionScript function with the ExternalInterface. The function fills in some text, then starts a timer. Next, we call an anonymous JavaScript function. This function tells the window, when it’s been resized, it must call back to our anonymous ActionScript function.

package
{
	import fl.events.ColorPickerEvent;
	import flash.display.MovieClip;
	public class Main extends MovieClip {
		public function Main() {
			cp.addEventListener(ColorPickerEvent.CHANGE, colorChange);
			ExternalInterface.addCallback("receiveText", receiveText);
			prompt.addEventListener(MouseEvent.CLICK, promptClick);
			change.addEventListener(MouseEvent.CLICK, changeClick);

			//create a new timer with a one second tick, and add an event listener
			var timer:Timer = new Timer(1000);
			timer.addEventListener(TimerEvent.TIMER, onTimer);

			anonymous();   //set up the anonymous functions
		}

		public function colorChange(event:ColorPickerEvent):void {
			ExternalInterface.call("receiveColor", event.target.hexValue);
		}

		public function receiveText(value:String):void {
			jsText.text = value;
		}

		public function promptClick(event:MouseEvent):void {
			promptText.text = "You said your name is: " + ExternalInterface.call("prompt", "What is your name?");
		}

		public function changeClick(event:MouseEvent):void {
			ExternalInterface.call("function(param){ document.getElementById('textChange').innerHTML = param; }", changeText.text);
			changeText.text = "";
		}

		//clear the text after one second has passed
		public function onTimer(event:TimerEvent):void {
			resizeText.text = "";
			timer.stop();
		}

		public function anonymous():void {
			//see how we're defining a function inside another function?
			ExternalInterface.addCallback("anon", function(){
				resizeText.text = "The window has been resized.";
				timer.start();
			});

			//same applies here
			ExternalInterface.call("function(){ window.onresize = function(){ document['externalInterface'].anon(); }; }");
		}
	}
}

(New lines are 12-16 and 36-51.)


Conclusion

The ExternalInterface is an extremely powerful and useful class. With it, you can receive values and events, all outside of the SWF. Have fun with it and thanks for reading!

Tags: Tips
Add Comment

Discussion 14 Comments

  1. Andrew Steenbuck says:

    Hey, great tip! External Interface has saved my butt on a number of occasions.

  2. Joao Aliano says:

    Fantastique! Fun, simple and extremely useful =)

  3. André says:

    One of the best explanations about ExternalInterface i ever seen!!
    Congratulations…

    I use ExternalInterface to create a DeepLinking class (like SWFAddress), it´s so usefull

  4. kevin says:

    this is exactly what i m looking for,you ROCK! man

  5. WebGuide4U says:

    Great explanation on this though i hate flash but still quite interesting

  6. Adrian says:

    I found one minor mistake in step 9; the anonymous() is missing. Apart from that it was a interesting read.

  7. just great didnt know i can do that thanks for that

  8. mutiu says:

    very useful… thanks.

  9. kedicik says:

    very good!

  10. marinella says:

    Ciao, there is something wrong on my code on step 4
    when i link the Main.as the color picker starts to blick:
    http://test.neuronica.it/flash_01/externalinterface.html

    It has to be somethink basic, it is my first approach width the actionscript 3.
    I did the Set up a Document Class Tutorial and it looked simple … bah!

    Grazie!

  11. mysti says:

    Hi,
    is there a way to call a html page?
    i mean someting like
    ExternalInterface.call(“myhtml.html”);
    inside a sort of frame inside the index page?
    thanks a lot!

  12. Christos K. says:

    Hello people

    Any help is welcome, about a problem with my swf object. In index.html (home page) to play as it is, but in every other page to not reload the intro part, and animations about the buttons actions and behaviours to stay in each page freeze on the left side of the flash frame/window.

    Buttons links are like these: index.html – about.html – certif.html …

    This is the my test site if you want to check it.

    http://www.kivisis-testweb.site90.net

    P.S.

    Sorry about my not so good English.

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.