jamie holliday
jamie holliday

Reputation: 1627

AS 3 Call function in parent from child movieclip

I have a container swf called main.swf that loads child swf's into a container using the Loader class.

In AS2 I could call functions of the main.swf container using

_root.someFunction();

Is AS3 I am having a problem how to do this.

I have tried using:

MovieClip(root.parent.parent).someFunction();

(get root of child.swf, parent is loader, parent is main.swf)

but this is coming up as null

Is there any way to do this so that it does not throw an error in the child swf and works when loaded into main swf?

Upvotes: 1

Views: 21226

Answers (5)

James LeMay
James LeMay

Reputation: 53

If clip B is inside clip A (or clip B is inside root), and you want to call "someFunction" that resides in A/root from clip B, this dot notation worked for me:

MovieClip(this.parent).someFunction();

Upvotes: 0

Rohmanto
Rohmanto

Reputation: 21

it works! just change "_root" with "MovieClip(root)" like this action script 2

_root.movieclip1.stop();

action script 3

MovieClip(root).movieclip1.stop();

"movieclip1" is instance name

its work !

Upvotes: 2

Adam Bass
Adam Bass

Reputation: 1

I was having this same problem, updating my AS2 code to AS3. But I was using an array to call a whole list of SWFs to load one after another automatically without a button.

I took your solution to this problem and molded to fit my needs and it worked! For anyone who wants my code, here it is:

Container (Parent) SWF that calls the loader to load the array of SWFs (on the 1st frame of the timeline):

import flash.net.URLRequest;
stop();

// Module Name and pages //

var mcArray:Array = new Array("swf/1-Intro.swf",
                        "swf/2-DOTdefinition.swf",
                        "swf/3-HazardousTable.swf",
                        "swf/4-BillsofLading.swf",
                        "swf/5-PaperBillsofLading.swf",
                        "swf/6-ReturnsManifest_v2.swf",
                        "swf/7-BillsOfLading.swf",
                        "swf/8-HazardClasses.swf",
                        "swf/9-HazardClasses2.swf",
                        "swf/11-ORMD.swf",
                        "swf/12-ID_Number.swf",
                        "swf/13-PackingGroup.swf",
                        "swf/14-ThinkAboutIt.swf",
                        "swf/15-EmergencyResponseBook.swf",
                        "swf/16-Labels.swf",
                        "swf/17-WhyKeepRecords_P1.swf",
                        "swf/17-WhyKeepRecords_P2.swf",
                        "swf/18-EmergencyResponseProcedures.swf",
                        "swf/19-SpillManagement.swf",
                        "swf/20-PreventativeMeasures.swf",
                        "swf/21-Security_v3.swf",
                        "swf/22-Certification.swf");

// Movie Clip Loader

var myMCL:Loader = new Loader();
var curFrameNum:Number = 0;

myMCL.addEventListener(Event.COMPLETE, loadNext);

function loadNext() { //this should be a global variable
var url:String = mcArray[curFrameNum];
var urlRequest:URLRequest = new URLRequest(url);
myMCL.load(urlRequest);
addChild(myMCL);
curFrameNum++;
}

loadNext();

The call to the parent method put on the last frame of each SWF movie (child):

stop();
parent.parent.loadNext();

Upvotes: 0

AsTheWormTurns
AsTheWormTurns

Reputation: 1316

I don't know if your code is in the Timeline or in a class. I think it is in the first frame of the timeline. If so, in A.swf you could have:

function someFunction():void{
    trace("called from B.swf");
}
//
var mLoader:Loader = new Loader();
var mRequest:URLRequest = new URLRequest("B.swf");
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
mLoader.load(mRequest);
//
function onCompleteHandler(loadEvent:Event):void
{
       container.addChild(loadEvent.currentTarget.content);
}

and in your B.swf (loaded by A.swf into a movieclip with instance name "container"):

btn.addEventListener(MouseEvent.MOUSE_DOWN,callA);
//
function callA(e:MouseEvent)
{
    if (this.parent.parent != null)
    {
        var p:MovieClip = this.parent.parent as MovieClip;
        p.someFunction();
    }
}

Not very elegant, but it should work. I would use Events, but you asked direct function calls.

Upvotes: 4

Diode
Diode

Reputation: 25145

This can be achieved by calling parent.parent.somefunction();

I am giving an example below

Parent Sprite

public class Main1 extends Sprite
{
    public function Main1()
    {
        super();

        var loader:Loader = new Loader();
        addChild(loader);
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function():void{
            trace("I am parent ....  I am calling a child function");
            Object(loader.content).invoke();

        });
        loader.load(new URLRequest("Sample1.swf"));

    }

    public function invoke():void{
        trace("I am parent ....  Child invoked this function");
    }
}

Child Sprite

public class Sample1 extends Sprite
{
    public function Sample1()
    {
        super();
    }


    public function invoke():void{
        trace("I am child ....  I am calling parent function");
        (Object(parent.parent)).invoke();   
    }


}

Running Main1 after compiling Sample1 should give the following trace

I am parent .... I am calling a child function

I am child .... I am calling parent function

I am parent .... Child invoked this function

Upvotes: 2

Related Questions