Home > Lab, as3 > Method of removing all event listeners

Method of removing all event listeners

January 26th, 2009

So over the weekend I was talking to a buddy of mine in regards to different ways of removing event listeners from objects. The way that I usually do it is that everything that requires a listener is placed in a “addListeners” method and and its counter part is placed in a “removeListeners” method. That’s a very simple way of doing it. It works all the time as long as you are on top of every single object that requires having a listener added and you place it on both functions.

Don’t get me wrong, that work around works pretty good but becomes sort of a drag at times (eh, call me lazy) so I came up with a more automated way of doing it! A little disclaimer though, the method that I am about to describe works in 99.9% of my cases because all my classes extend an abstract class of some sort. Anyway, let me show you how I go about it:

What I do is archive all the added listeners and then remove them later in a loop. Everything is done at the abstract class level

private var arrListeners:Array = [];

I then override the “addEventListener” method in order to push references into the array as so:

override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
{
        super.addEventListener(type, listener, useCapture, priority, useWeakReference);
        arrListeners.push({type:type, listener:listener});
}

Now that you have a way to reference the added listeners, you would loop through the array to remove the listeners which still exist when needed:

private function clearEvents():void
{
   for(var i:Number = 0; i<arrListeners.length; i++){
      if(this.hasEventListener(arrListeners[i].type){
         this.removeEventListener(arrListeners[i].type, arrListeners[i].listener);
      }
   }
   arrListeners = null
}

That’s basically it. After that, if the object does not extend a class with that method, then I would just use the first method mentioned above.

You can download a quick example here. If you guys have any other ways of doing it, or can enhance the way that I am doing it now, please do let me know. Hope this helps!

Lab, as3

  1. January 26th, 2009 at 17:12 | #1

    Hy Reyco1,

    I´ve done the exact same thing you did with this abstract class, but I came across another problem. Like you mentioned in you example the stage didnt registered it´s events since you can not override stage eventdispatcher.
    And it would be also hard to manage the events from objects like sound, video, loader and so on.

    So I´ve done a class similar to yours but I pass the obj that will dispatch the events. It´s something like this:

    THE CLASS:

    package  
    {
        import flash.events.EventDispatcher;
       
        /**
         * ...
         * @author ...
         */

        public class EventHandler extends EventDispatcher
        {
            private var eventList:Array;
            private var _dispatcher:*;
            public function EventHandler(dispatcher:*)
            {
                eventList = new Array();
                _dispatcher = dispatcher;
            }
           
            override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = true):void
            {
                eventList.push( { TYPE:type, LISTENER:listener } );
               
                if (_dispatcher.hasEventListener(type))
                {
                    _dispatcher.removeEventListener(type, listener);
                }
               
                _dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
            }
           
            public function RemoveEvent(type:String):void
            {
                var total:int = eventList.length ;
                for (var i:int = 0; i &lt; total; i++)
                {
                    if (eventList[i].TYPE == type)
                    {
                        _dispatcher.removeEventListener(eventList[i].TYPE, eventList[i].LISTENER);
                        eventList.splice(i, 1);
                        total = eventList.length;                  
                    }              
                }
            }
             
           
            public function RemoveEvents():void
            {
                var total:int = eventList.length ;
                for (var i:int = 0; i &lt; total; i++)
                {
                    _dispatcher.removeEventListener(eventList[i].TYPE, eventList[i].LISTENER);
                }
                eventList = [];
            }
           
        }
       
    }

    HOW TO:

    package  
    {
       
        import flash.display.Graphics;
        import flash.display.MovieClip;
        import flash.events.MouseEvent;
        /**
         * ...
         * @author ...
         */

        public class Main extends MovieClip
        {
            private var boxSample:MovieClip;
            public function Main()
            {
                CreateEvents();
            }
            private function CreateEvents():void
            {
                boxSample = new MovieClip();
                var graph:Graphics = boxSample.graphics;
                graph.beginFill(0xff0000);
                graph.drawRect(0, 0, 200, 200);
                graph.endFill();
               
                stage.addChild(boxSample);
               
                var boxSampleEvent:EventHandler = new EventHandler(boxSample);
                boxSampleEvent.addEventListener(MouseEvent.CLICK, OnClick);
                boxSampleEvent.addEventListener(MouseEvent.MOUSE_DOWN, OnDown);
               
                //to remove all events
                //boxSampleEvent.RemoveEvents();
               
                //to remove only one event
                boxSampleEvent.RemoveEvent(MouseEvent.MOUSE_DOWN);
               
                ////////STAGE EVENTS///////////////////////////////////
                var stageEventHandler:EventHandler = new EventHandler(stage);
                stageEventHandler.addEventListener(MouseEvent.CLICK, OnStageClick);
                stageEventHandler.addEventListener(MouseEvent.MOUSE_DOWN, OnStageMouseDown);
               
                //to remove all events
                //stageEventHandler.RemoveEvents();
               
                //to remove only one event
                stageEventHandler.RemoveEvent(MouseEvent.MOUSE_DOWN);          
               
               
            }
            //BOX
            private function OnDown(e:MouseEvent):void
            {
                trace("box mouse down");
            }
           
            private function OnClick(e:MouseEvent):void
            {
                trace("box mouse click");
            }
           
            //STAGE
            private function OnStageMouseDown(e:MouseEvent):void
            {
                trace("stage mouse down");
            }
           
            private function OnStageClick(e:MouseEvent):void
            {
                trace("stage click");
            }
        }
       
    }
  2. admin
    February 3rd, 2009 at 09:10 | #2

    That looks pretty good! That coupled with the Abstract class should handle all, if not most, of lingering events. Good Job!

  3. February 5th, 2009 at 03:21 | #3

    @admin
    Thank´s, your blog is very cool…always updated with some interesting stuff.
    I´ve became a reader.
    Hope to see some great posts about JigLib …

  4. Brian
    September 4th, 2009 at 06:44 | #4

    Thanks for this!

  5. Aaren
    October 5th, 2009 at 14:31 | #5

    Don’t forget that events registered with ‘useCapture’ are treated as two separate handlers.

    var oListener:Object = arrListeners[i];
    this.removeEventListener(oListener.type, oListener.listener, true);
    this.removeEventListener(oListener.type, oListener.listener, false);

    should work fine.

    I’m more of a destructor fan myself, and 90% you want to clear all listeners is because it’s about to be destroyed. Other than that, I remove listeners as soon as their no longer needed. I get what your saying though, a generic event listener remover.

  1. No trackbacks yet.
Comments are closed.