Archive | JavaScript RSS for this section

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?

Advertisements

Crossdomain function calling from iframe to parent page

If the iframe Page B and the top Page A share the same top-level domain,but not the second-level domain,you can simply add this line to your code in order to assign the calling accessment from Page B to A

document.domain = "top-level-domain.com";

If the iframe Page B is placed on a totally different domain,then what?Still there is a way.
Basically,I achieved this by refreshing the location(src) value of the other iframe.

1.Define a function for calling in Page A:

function waiting4Callback(_p:String)
{
	alert("hello:" + _p);
}

2.Iframe Page B on Page A:

<i_frame id="IFrame_PageB" marginWidth=0 marginHeight=0 src="web-address-of-Page-B" frameBorder=0 scrolling="no" width="1000" height="500"></i_frame>

If you try to call A’s function immediately in Page B,obviously it is illegal and maybe it will cause an Error on your broswer.

window.parent.waiting4Callback("hello A");

3.The solution is to create a Page C which will be iframed later by Page B,and add this javascript code in Page C:

window.parent.parent.waiting4Callback( window.location.hash.substring(1));

4.Place the proxy.html file together with Page A and ensure that they share exactly the same domain

5.Add this iframe node on Page B in order to iframe Page C:

<i_frame id="IFrame_PageC" name="IFrame_PageC" marginWidth=0 marginHeight=0 src="" frameBorder=0 width="0" scrolling=0 height="0"></i_frame>

6.Now you can call Page A’s function and send Param in Page B like this:

document.getElementById("IFrame_PageC").src = "http://address-of-page-c.html" + "?random_anti_cache="+Math.random()+"#"+"String param to be sent";

In step 6,the Page C is refeshed by Page B,so the command added in step 3 executes to help Page C receive the String param from the value of “window.location.hash”.
Meanwhile,”window.parent.parent” in Page C refers to Page A,with which Page C shares the same domain.They don’t have any problem in communicating with each other,so in the scope of Page C,callback can be successfully sent to Page A.

*Please replace “i_frame” with “iframe” in the html code above