1
votes

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?

2
Maybe try removing this., or storing this in an object. - ToddBFisher

2 Answers

1
votes

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.

0
votes

Let me explain what is happening in your code.

When we declare a function in addEventListener like the following ( or the way you did )

object.addEventListener(event, function(){


});

the function will be created in global namespace and inside the function this will refer to global object. Usually we use a proxy variable to store the instance of the object in similar situations. So it can be fixed by doing the following

var _this = this;
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");
}

But usually we do this in Javascript.

The structure of your code has to be changed. Please see the anwser posted by @WiseOldDuck. That is the way to do it in Actionscript