Getting data into flash: swfobject 2 and ExternalInterface (as3)
Using swfobject v.2 is a great way to embed your swf and pass it flash variables, but to pass it a data object, you would use javascript and connect it to the ExternalInterface from the flash. There I ran into a snag.
The snag being that it didn’t work anymore. When I added the callback – in actionscript: ExternalInterface.addCallback – and called it from a window.onload event in javascript, it no longer worked; nor did it with the callback function in swfobject 2. It used to work in earlier versions. The documentation on Google only points to the static replacement technique (works), but I really don’t want to use that method. The Adobe documentation uses a timer, checking javascript availability from the flash – which I thought was too complex and verbose, just for demonstration purposes. But I used this method anyway; I did shorten it a bit.
Anyhoo – here’s how I got it to work. Roughly:
- there’s an object with data available in your javascript: for example getDataObj() constructs and returns an object with data
- swfobject.embedSWF replaces a DOM-element with the swf-object on the page
- the swf loads, and starts waiting for data with the callback function eiDataReceiver
- the swf calls javascript to see whether the function onSwfLoaded() is available (so no need for window.onload function)
- this onSwfLoaded() calls the actionscript function eiDataReceiver that passes it the data-object
- tada, the swf starts up with a restored data set.
The example below is used to get data from javascript into the swf, implementing swfobject 2 dynamic replacement and AS3 ExternalInterface.
in actionscript:
import flash.external.*;
import flash.utils.Timer;
//
private function checkForJSData():void{
//add callback to receive data from javascript
if(ExternalInterface.available) {
try{
trace('inside try EI');
ExternalInterface.addCallback("eiDataReceiver", onReceivedFromJavaScript);
if(!jsReadyState()) checkForJavascript();
}catch(err:Error){
trace("An EI error occurred: " + err.message + "\n");
}
}
}
//
private function checkForJavascript():void{
var readyTimer:Timer = new Timer(50, 0);
readyTimer.addEventListener(TimerEvent.TIMER, timerHandler);
readyTimer.start();
}
private function timerHandler(evt:TimerEvent):void {
var isReady:Boolean = jsReadyState();
if (isReady) Timer(evt.target).stop();
}
private function jsReadyState():Boolean{
var readyState:Boolean = ExternalInterface.call("onSwfLoaded");
return readyState;
}
private function onReceivedFromJavaScript($obj:Object):void {
if($obj!=null) GlobalVars.jsData = $obj;
}
in javascript:
//replaces element with id "circlegame" with flash object
var flashvars = {xmlUrl: "swf/data/colorset_01.xml", debugMode: "on"};
var params = {wmode:"opaque", allowscriptaccess:"always" };
var attributes = {id:"circlegame", name:"circlegame"};
//
swfobject.embedSWF("swf/netwerkcirkels.swf", "circlegame", "940", "540", "9.0.0", "swf/expressinstall.swf", flashvars, params, attributes);
//
function onSwfLoaded(){
//calls AS fuction "eiDataReceiver" in the swf and passses the data to it
document.getElementById("circlegame").eiDataReceiver( getDataObj() );
//notify flash that js has loaded:
return true;
}
The function getDataObj() is not included in this example; it constructs and returns an object with data, which immediately can be used by the actionscript without having to parse it.
In snippets:
Featured projects:
Most popular:
RSS Links