Unloading an external .swf within itself in action script 3 - actionscript-3

I have been trying to look for a method, I've tried numerous code examples none have worked.
This is the code I'm using in my my main .SWF file to load the external .swf file called (Stage4.swf). How can unload this swf file while it's load within the Stage4.swf file?
var child_loader:Loader = new Loader();
addChild(child_loader);
var url:URLRequest = new URLRequest("Stage4.swf");
child_loader.load(url);
child_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, load_completed);
child_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, on_progress);
function load_completed(e:Event):void {
child_loader.x = 0;
child_loader.y = 0;
}
function on_progress(e:ProgressEvent):void {
trace(e.bytesLoaded + " out of " + e.bytesTotal);
}

You should make the child SWF to dispatch a custom Event that will be listened by its parent. Most likely your code snippets don't work because the stack contains the child SWF's code. Something like this:
public static const UNLOAD_SWF:String='unload_swf';
...
function load_completed(e:Event):void {
this.addEventListener(UNLOAD_SWF,doUnload);
// rest of code
}
function doUnload(e:Event):void {
removeEventListener(UNLOAD_SWF,doUnload);
addEventListener(Event.ENTER_FRAME,unloadNow);
}
function unloadNow(e:Event):void {
removeEventListener(Event.ENTER_FRAME,unloadNow);
child_loader.unloadAndStop(); // should work now
}

Related

How to load a SharedObject from another Swf file in actionScript 3.0

This code works, but when I put the loadBtn and the function 'loadNames' in another swf file, the program traces this: "saved names: undefined", in addition I'd like to specify the path of the object saved:how can i do that?
var SO:SharedObject=SharedObject.getLocal("mySave");
var archive:Array=new Array();
var counter:Number=-1;
saveBtn.addEventListener(MouseEvent.CLICK, saveName);
loadBtn.addEventListener(MouseEvent.CLICK, loadNames);
function saveName(event:Event) {
counter++;
archive[counter]=input.text;
SO.data.arrSaved=archive;
SO.flush();
}
function loadNames(event:Event) {
trace("saved names: "+SO.data.arrSaved);
}

Actionscript: SWF file does not record data to txt, while the compiler does

I am trying to create a psychological experiment in ActionScript. The performance of the participants is to be stored in a separate .csv file. I have written this code (apparently, instead of "This is the text to write" there is going to be a data array, but the problem appears with this code on equal parts)
import flash.net.FileReference;
import flash.events.Event;
var hint:String = "Please give a name for the file";
var labelling:String;
experiment_label.addEventListener(KeyboardEvent.KEY_UP, enter_pressed)
function enter_pressed (event:KeyboardEvent):void{
if (event.keyCode == 13) {
labelling = experiment_label.text;
addEventListener(Event.ENTER_FRAME,saveFile);
var ss:String = "this is text to write";
var fileRef:FileReference;
fileRef = new FileReference();
function saveFile(event:Event):void
{
fileRef.save(ss, labelling+".csv");
removeEventListener(Event.ENTER_FRAME, saveFile);
}
}
}
The problem I am facing is as follows: when I run it in from under Flash, it operates perfectly, and the save window does pop up. However, if I run an .swf file separately, it just ignores saving command.
Could you kindly suggest, what can I do? Or maybe I should use a different approach to saving altogether?
You current code will give you an Error #2176 (use a try ... catch to catch it) because FileReference.save()
is not called in response to a user action, such as a mouse event or keypress event.
To avoid that, you have to remove the Event.ENTER_FRAME event listener, even you don't need it :
function on_KeyUp(event:KeyboardEvent):void
{
if (event.keyCode == 13)
{
save_File();
}
}
function save_File():void
{
try
{
var fileRef:FileReference = new FileReference();
fileRef.save('some text here', 'my_file.csv');
}
catch (e:Error)
{
trace(e.toString());
}
}
Hope that can help.

How to run JavaScript dynamically in a Flex AIR application?

What is the easiest way I can run JavaScript dynamically in a Flex or ActionScript AIR application?
This is what I have so far. It does not work yet and htmlComponent.domWindow is so far null:
if (htmlComponent==null) {
htmlComponent = new HTML();
htmlComponent.htmlText = "<html><script>"+myJavaScript+"</script><body></body></html>";
htmlComponent.addEventListener("complete", function(e:Event):void {trace('html load complete');});
IInvalidating(htmlComponent).validateNow();
}
if (htmlComponent.domWindow && htmlComponent.domWindow.validateXML) {
result = htmlComponent.domWindow.validateXML(value);
}
Your issue, is likely that you do not wait for the loading of the content to actually load. So when your code runs, the DOM is still empty.
var htmlText:String = "<html><script>"+myJavaScript+"</script><body></body></html>";
htmlLoader = new HTMLLoader();
htmlLoader.loadString(htmlText);
// add a complete handler and don't reference the DOM until it's complete
htmlLoader.addEventListener(Event.COMPLETE, loadComplete);
function loadComplete(e:Event):void {
if (htmlLoader.domWindow && htmlLoader.domWindow.myFunction){
//...do what you need to with the domWindow
}
}

Open external .swf in another frame or window

I am trying to link to an external .swf file, which I have done, but it opens as a popup within the main .swf. What I want to do is either have it navigate to a blank frame with the external .swf there or have it open in a new window. How do I achieve this?
Here is the code I have which opens the external .swf:
private function openSWF():void {
cSWFLoader = new Loader();
cSWFPopup = addChild(cSWFLoader);
cSWFLoader.x = cPopX;
cSWFLoader.y = cPopY;
try {
cSWFLoader.load(new URLRequest(cSourceFile));
cSWFLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, SWFLoaded);
}catch (err:Error){
trace("YOU DONE GOOFED", cSourceFile);
trace("Error: ", err);
cSourceFile = null;
}
}
private function SWFLoaded(evt:Event):void{
cSWFLoader.addEventListener(MouseEvent.MOUSE_DOWN, dragSWF);
cSWFLoader.addEventListener(MouseEvent.MOUSE_UP, dropSWF);
cSWFPopup.content.gotoAndStop(cFrameLabel);
cSWFPopup.content.closeBtn.addEventListener(MouseEvent.CLICK, closeSWF);
cSWFLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, SWFLoaded);
}
Thanks in advance

AS3 add callbacks for listeners

lately I've been asked to change a small flash app i made to work with external callbacks instead of using the embedded buttons.
I tried to automate the process and came up with this function:
/**
* Add an External callback for all PUBLIC methods that listen to 'listenerType' in 'listenersHolder'.
* #param listenersHolder - the class that holds the listeners we want to expose.
* #param listenerType - a String with the name of the event type we want to replace with the external callback.
*/
public static function addCallbacksForListeners(listenersHolder:*, listenerType:String):void
{
// get the holder description
var description:XML = describeType(listenersHolder);
// go over the methods
for each(var methodXML:XML in description..method)
{
// go over the methods parameters
for each(var parameterXML:XML in methodXML..parameter)
{
// look for the requested listener type
var parameterType:String = parameterXML.#type;
if (parameterType.indexOf(listenerType) > -1)
{
var methodName:String = methodXML.#name;
trace("Found: " + methodName);
// get the actual method
var method:Function = listenersHolder[methodName];
// add the callback
try
{
ExternalInterface.addCallback(methodName, method);
trace("A new callback was added for " + methodName);
}
catch (err:Error)
{
trace("Error adding callback for " + methodName);
trace(err.message);
}
}
}
}
before using this function I had to change the listener's function to Public, add null default parameter and of course remove/hide the visuals.
for example, from :
private function onB1Click(e:MouseEvent):void
to :
public function onB1Click(e:MouseEvent = null):void
add this line to the init/onAddedToStage function:
addCallbacksForListeners(this, "MouseEvent");
and remove the button from stage or just comment the line that adds it.
My question is: can you find a better/ more efficient way to do that ?
any feedback is welcomed..
Maybe you should make the javascript to call a single method with different functionName param. Then you only need to add one callback and you don't need to make all those functions public.
ExternalInterface.addCallback('callback', onCallback);
public function onCallback(res:Object)
{
var functionName:String = res.functionName;
this[functionName]();
}