Leak free event class that doesn’t use the unload event

June 9th, 2008 by Spocke

I recently read an interesting blog post at Ajaxian it described that Hedger Wang discovered that some Chinese fellow was able to fix the circular reference memory leak in IE using a finally statement. This got me very exited since it would remove the need to use the unload event to cleanup memory leaks. There are lots of issues using the unload event to cleanup memory leaks I blogged about one of them earlier and using an non unload approach would make things a lot easier and more efficient.

Here is the proof of concept class and you can see it in action at the example page.

(function() {
	window.EventUtils = {
		eventFuncs : [],

		addEvent : function(o, n, f) {
			var el, id;

			// Resolve element by id if needed
			o = typeof(o) == 'string' ? document.getElementById(o) : o;

			if (o.attachEvent) {
				// Since we can't use attachEvent we need to generate an unique id for the object
				// and place functions in an array one for each object
				el = EventUtils.eventFuncs;
				id = o._evtID;

				if (!el[id]) {
					// Generate new unique id
					id = o._evtID = el.length;

					// Add event listener old fashion way instead of attachEvent
					o['on' + n] = function() {
						var i, l, e = window.event, li;

						e.target = e.srcElement; // Force W3C style

						// Execute each event listener in order
						for (i = 0, li = el[e.target._evtID], l = li.length; i < l; i++)
							li[i](e);
					};

					// Create array with first function
					el[id] = [f];
				} else
					el[id].push(f); // Push in more functions

				// Fix the IE leak
				o = null;
			} else if (o.addEventListener)
				o.addEventListener(n, f, false);
			else
				o['on' + n] = f;

			return f;
		},

		removeEvent : function(o, n, f) {
			var i, li;

			// Resolve element by id if needed
			o = typeof(o) == 'string' ? document.getElementById(o) : o;

			if (o.detachEvent) {
				li = EventUtils.eventFuncs[o._evtID];

				if (li) {
					// Detach event listener by looking for it and remove it from the array
					for (i = 0; i < li.length; i++) {
						if (li[i] === f)
							li.splice(i, 1);
					}
				}
			} else if (o.removeEventListener)
				o.removeEventListener(n, f, false);
			else
				o['on' + n] = null;
		}
	};
})();

Here is a simple example on how to use the class it adds two events and removes one of them this sample code can be seen live running the example page:

var f;

EventUtils.addEvent('elm', 'click', function(e) {
	alert('Listener 1: ' + e.target.id);
});

f = EventUtils.addEvent('elm', 'click', function(e) {
	alert('Listener 2: ' + e.target.id);
});

EventUtils.addEvent('elm', 'click', function(e) {
	alert('Listener 3: ' + e.target.id);
});

EventUtils.removeEvent('elm', 'click', f);

Posted in Blogs, Cool stuff, Development | Comments Off

The Blog is up!

April 3rd, 2008 by admin

We never really thought we would be the type of ppl that uses blogs, we have so many places where we could post news and stuff, but I guess here we can be somewhat less serious and just post some fun and cool stuff related to what we do for a living.

Will try to keep this up to date with a few articles per week.

Posted in Blogs | 2 Comments »

Next Entries »