Search code examples
flashactionscript-3event-handling

Flash AS3 get parent frame reference from inside a function


This is my code in Flash/AS3, in a frame's action:

import flash.events.Event;

stop();

this.addEventListener(Event.ENTER_FRAME, loading);

function loading(e:Event):void{

    var total:Number = this.stage.loaderInfo.bytesTotal;
    var loaded:Number = this.stage.loaderInfo.bytesLoaded;

    if (total == loaded){

       var splashTimer:Timer = new Timer(3000,1);
       splashTimer.addEventListener(TimerEvent.TIMER_COMPLETE, splashTimer1);
       splashTimer.start();
       function splashTimer1(evt:TimerEvent):void
       {
          //remove the enter frame event listener here
          this.removeEventListener(Event.ENTER_FRAME, loading);
          gotoAndPlay("3");
       }

    }

}

I want to remove the enter frame event listener (loading()), inside that splashTimer event handler, before redirecting to frame 3. As you can see, I used:

this.removeEventListener(Event.ENTER_FRAME, loading);

But it throws me a run-time error:

TypeError: Error #1006: removeEventListener is not a function.
    at Function/<anonymous>()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at flash.utils::Timer/tick()

This is because I believe it is referring the splashTimer1 function by "this".

How can I refer to parent frame there, so that I can remove its event listener?


Solution

  • I would pull the function out and place it at the same level as loading:

    this.addEventListener(Event.ENTER_FRAME, loading); 
    
    function splashTimer1(evt:TimerEvent):void
    {
       //remove the enter frame event listener here
       this.removeEventListener(Event.ENTER_FRAME, loading);
       gotoAndPlay("3");
    }
    
    function loading(e:Event):void{
    
    var total:Number = this.stage.loaderInfo.bytesTotal;
    var loaded:Number = this.stage.loaderInfo.bytesLoaded;
    
    if (total == loaded){
    
       var splashTimer:Timer = new Timer(3000,1);
       splashTimer.addEventListener(TimerEvent.TIMER_COMPLETE, splashTimer1);
       splashTimer.start();
    

    etc...

    then this will refer to the MovieClip instead of the nested function.

    You could also add a go-between var like:

    if (total == loaded){
    
      var splashTimer:Timer = new Timer(3000,1);
      splashTimer.addEventListener(TimerEvent.TIMER_COMPLETE, splashTimer1);
      splashTimer.start();
    
      var theMC:MovieClip = this;
    
      function splashTimer1(evt:TimerEvent):void
      {
         //remove the enter frame event listener here
         theMC.removeEventListener(Event.ENTER_FRAME, theMC.loading);
         theMC.gotoAndPlay("3");
      }
    

    etc...

    but I like the first approach better.