Flash AS3 EventListeners Tutorial: Easily Add, Retrieve and Remove ALL Event Listeners
Did you know that when you remove objects from the stage it doesn’t remove the event listeners too? How annoying!! In researching this problem I’ve found several classes which manage event listeners — only none of them were setup to keep track of event listeners on groups of objects.
What if you wanted to keep track of ALL event listeners on ALL objects of the same type? For example, what if you wanted to find all event listeners registered to buttons, or all event listeners registered to movie clips? That’s where my EventHandler class comes into play.
Instead of keeping track of event listeners registered to a single movie clip, sprite or button this class keeps track of all event listeners on all objects of the same type. This class allows you to easily add, remove or retrieve event listeners on ALL buttons, sprites or movie clips.
/*************** * File: shell/Events.as * Author: design1online.com, LLC * Created: 10.31.2010 * Purpose: keep track of all event listeners ***************/ package com.design1online.events { import flash.events.EventDispatcher; public class EventHandler extends EventDispatcher { private var dispatchList:Array; private var eventList:Array; /*** * Purpose: default constructor * Precondition: a reference to the object with event handlers registered to it * Postcondition: a list of the event listeners has been created ***/ public function EventHandler() { this.eventList = []; this.dispatchList = []; } /*** * Purpose: add an event listener * Precondition: type of listener, function, use capture, priority and weak reference * Postcondition: event listener added to the object and the list ***/ public function addEvtListener(dispatch:*, type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=true):void { if (!dispatch.hasEventListener(type)) { dispatchList.push({func:dispatch, name:dispatch.name}); eventList.push({type:type, listener:listener, useCapture:useCapture}); dispatch.addEventListener(type, listener, useCapture, priority, useWeakReference); } else trace("EventHandler Error: " + type + " already exists for " + dispatch.name); } /*** * Purpose: remove an event listener * Precondition: the type, listener and use capture * Postcondition: event listener removed from the object and list ***/ public function removeEvtListener(dispatcher:*, type:String, listener:Function, useCapture:Boolean=false):void { var obj:Object; var dispatch:*; var i:uint = 0; while(i < eventList.length) { obj = eventList[i]; dispatch = dispatchList[i].func; if (dispatch == dispatcher && obj.type == type && obj.listener == listener && obj.useCapture == useCapture) { dispatch.removeEventListener(type, listener, useCapture); dispatchList.splice(i, 1); eventList.splice(i, 1); break; } ++i; } dispatch = null; obj = null; } /*** * Purpose: remove all event listeners on this object * Precondition: the object to remove listeners from * Postcondition: all listeners have been removed ***/ public function removeAllEventListeners():void { var obj:Object; var dispatch:*; var i:uint = 0; while(i < eventList.length) { obj = eventList[i]; dispatch = dispatchList[i].func; dispatch.removeEventListener(obj.type, obj.listener, obj.useCapture); ++i; } obj = null; dispatch = null; dispatchList = []; eventList = []; } /*** * Purpose: returns a list of all current event listeners * Precondition: the object you want listeners for * Postcondition: an array of listeners is returned ***/ public function getAllEventListeners():Array { var i:uint = 0; var arr:Array = []; while(i < eventList.length) { arr.push(dispatchList[i].name + ": " + eventList[i].type); ++i; } return arr; } } //end class } //end package
To see this class in action you’ll need to create a new flash project and add three buttons to the stage. Name them buttonOne and buttonTwo and buttonThree. Now you’re going to create an instance of the EventHandler to keep track of all the button event listeners.
import com.design1online.events.*; public var buttonEvents:EventHandler = new EventHandler(); buttonEvents.addEvtListener(buttonOne, MouseEvent.CLICK, clickedButtonOne); buttonEvents.addEvtListener(buttonTwo, MouseEvent.CLICK, clickedButtonTwo); buttonEvents.addEvtListener(buttonThree, MouseEvent.CLICK, clickedButtonThree); function clickedButtonOne(e:MouseEvent) { trace('clicked button one'); //this is how you would remove all of the button event listeners buttonEvents.removeAllEventListeners(); } function clickedButtonTwo(e:MouseEvent) { trace('clicked button two'); //this is how you would figure out which buttons have event listeners trace(buttonEvents.getAllEventListeners()); } function clickedButtonThree(e:MouseEvent) { trace('clicked button three'); //this is how you would remove a single button event buttonEvents.removeEvtListener(buttonThree, MouseEvent.CLICK); }
thank you for this code! do you have to make sure all the executed functions are “public” in order for them to be called from another class?
You’re welcome and yes they need to be public in order to call them from other classes.