Archive | September 2009

Communication from Javascript to Flash

If you’ve ever try to call a function from Javascript to Flash,you will find there’re dozens of issues,even if you followed every step of the offical documents. This post will help you fix these issues without using any plugin js.

1.Add flash embed code into the HTML code:

<!- for ie -->
<o_bject id="swf_ie" width="550" height="400" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">
	<param name="movie" value="test.swf" />
	<param name="allowScriptAccess" value="always" />
	<!- for other -->
	<e_mbed id="swf_other" src="test.swf" width="550" height="400" type="application/x-shockwave-flash" allowScriptAccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</o_bject>

Verify the allowScriptAccess value is always.Please replace o_bject to object,e_mbed to embed.

2.Add this code into Javascript:

function callFuncInSwf()
{
	document.getElementById(swfId).j2s_funcInSwf();
}
function s2j_checkInitAvailable()
{
	return "ok";
}
var isIE = document.all && window.external;
var swfId = "swf_" + (isIE ? "ie" : "other");

callFuncInSwf Function is the entrance for you to call the SWF inner funciton.
document.getElementById(swfId) refers to the SWF plugin reference,the last two lines show how to specify the refer from the different browser types(IE,Firefox,Chrome…).
j2s_funcInSwf is the function will be defined in SWF later.

3.Add this code into Flash:

import flash.external.*;
import flash.utils.Timer;
import flash.events.TimerEvent;

Security.allowDomain("*");
Security.allowInsecureDomain("*");

if (ExternalInterface.available)
{
	try
	{
		ExternalInterface.addCallback("__dummy_tryCallback", null);

		var readyTimer:Timer = new Timer(200,0);
		readyTimer.addEventListener(TimerEvent.TIMER, __onInitTimer);
		readyTimer.start();
		log("check...");
	}
	catch (error:SecurityError)
	{
		log("SecurityError : " + error.message);
	}
}
else
{
	log("External unavailable");
}

function __onInitTimer(evt:TimerEvent):void
{
	if (ExternalInterface.call("function(){try{if(s2j_checkInitAvailable()=='ok'){return true;}}catch(ex){}}"))
	{
		log("JS init check finished");
		Timer(evt.target).stop();
		ExternalInterface.addCallback("j2s_funcInSwf", swfInnerFunction);
	}
	else
	{
		log("Interval: waiting for JS response...");
	}
}

function swfInnerFunction():void
{
	log("swfInnerFunctioncall successful!");
}
function log(_txt:String)
{
	txt.appendText(_txt+"\n");
}

First,”ExternalInterface.available” verifies whether “ExternalInterface” function is avaliable in SWF.The excution will stop here if swf file was running individually,like debug in your FlashIDE.

Second,we use “ExternalInterface.addCallback” to check the communication policy between SWF and Javascript. If the SWF file doesn’t share the same domain with the HTML page and meanwhile you haven’t included “ Security.allowDomain(“*”);” in your code,the excution will stop here and catch “SecurityError“.

Then,we have to ensure the Javascript environment initialize avaliable.Due to the varities of the network and the browser mechanism,sometimes the SWF program is excutived before the Javascript.Therefore,we have to define an anonymous Function to keep trying call the function “s2j_checkInitAvailable” defined in Javascript till it returns “ok”.

After all of the steps above,the line “ExternalInterface.addCallback” can finally be excuted and will not cause Errors anymore.

Now check your program,which steps you’ve missed?