Event Package Part 1
For this article, I will be using the “attachFunc” and “detachFunc” methods outlined in my X-Browser Event Handling article.
Again, sorry about this late post. I am still working 14 hour days this week.
Today I will be introducing a simple event handler package. First, we will discuss the methods you might want to have in an Event Package and whether they are: required, frequently used, or nice to have.
Necessary Functions:
- Event.add - same as “attachFunc”
- Event.remove - same as “detachFunc”
Those two functions will allow you to add and remove any event from any element. This is all you need for event management, however, you may frequently wish to know about or change an event (such as triggering element or key code, and preventing default behavior). Here is a list of methods and variables that I frequently use:
Frequently Used Functions and Static Variables:
- Hash map of key codes - such as {KEY_BACKSPACE: 8}
- Hash map of event names - such as {CLICK: ‘click’}
- getEl - returns the element that owns this event
- getCode - returns the key code of the event
- stopDefault - stops the capture phase of the event
- stopProgation - stops the bubbling phase of an event
- stop - stops both the bubbling and capture phase of an event
Having static key codes is helpful, as you won’t need to look them up everytime you are listening for an “enter” key. I map the event Names because if you try to attach a ‘clck’ event, instead of a ‘click’ event, the browser does not throw an exception. However, your code is not going to work, but if you instead mispell your variable name, then the browser will throw an exception. Here are the function mentioned so far:
var Event = function() { // Private namespace var self = null; // Public namespace return { /** * Event name constants */ BLUR: ‘blur’, CLICK: ‘click’, DOUBLE_CLICK: ‘dblclick’, KEY_DOWN: ‘keydown’, KEY_PRESS: ‘keypress’, KEY_UP: ‘keyup’, LOAD: ‘load’, MOUSE_DOWN: ‘mousedown’, MOUSE_MOVE: ‘mousemove’, MOUSE_OVER: ‘mouseover’, MOUSE_OUT: ‘mouseout’, MOUSE_UP: ‘mouseup’, SUBMIT: ’submit’, UNLOAD: ‘unload’, /** * Common event keycodes */ KEY_BACKSPACE: 8, KEY_TAB: 9, KEY_RETURN: 13, KEY_ESC: 27, KEY_LEFT: 37, KEY_UP: 38, KEY_RIGHT: 39, KEY_DOWN: 40, KEY_DELETE: 46, KEY_HOME: 36, KEY_END: 35, KEY_PAGEUP: 33, KEY_PAGEDOWN: 34, KEY_SPACE: 32, /** * Attach a listener from an element; uses lazy loading to setup the add and remove functions * * @method add * @param el {HTMLElement} the element to bind the handler to * @param sType {string} the type of event handler * @param fn {function} the callback to invoke * @param fl {boolean} OPTIONAL: capture or bubble phase * @static */ add: function(el, eType, fn, capture) { self = Event; if (window.addEventListener) { self.add = function(el, eType, fn, capture) { el.addEventListener(eType, fn, capture); }; self.remove = function (el, eType, fn, capture) { el.removeEventListener(eType, fn, capture); }; } else if (window.attachEvent) { self.add = function(el, eType, fn, capture) { el.attachEvent(’on’ + eType, fn, capture); }; self.remove = function (el, eType, fn, capture) { el.detachEvent(’on’ + eType, fn, capture); }; } else { self.add = function() {}; } }, /** * Extend the Event Object with x-browser retrieval of keycode from event * * @method getCode * @param e {event} The triggering event * @static */ getCode: function(e) { var code = null; if (! e) {e = window.event;} if (e.keyCode) {code = e.keyCode;} else if (e.which) {code = e.which;} return code; }, /** * X-browser event target retrieval * * @param e {event} The triggering event * @param tagName {string} OPTIONAL: HTML tag name * @param className {string} OPTIONAL: HTML tag attribute class name * @static */ getEl: function(e, tagName, className) { if (! e) {e = window.event;} var targ = e.target || e.srcElement; if ($D.TEXT_NODE == targ.nodeType) {targ = targ.parentNode;} // defeat Safari bug if (tagName || className) {targ = Dom.getParent(targ, tagName, className);} return targ; }, /** * Remove a listener from an element * * @method remove * @param el {HTMLElement} the element to bind the handler to * @param sType {string} the type of event handler * @param fn {function} the callback to invoke * @param fl {boolean} OPTIONAL: capture or bubble phase * @static */ remove: function(el, eType, func, fl) {}, /** * Convenience method for stopPropagation + stopDefault * * @method stop * @param e {event} The triggering event * @static */ stop: function(e) { self.stopPropagation(e); self.preventDefault(e); }, /** * Prevents the default behavior of the event * * @method stopDefault * @param e {event} The triggering event * @static */ stopDefault: function(e) { if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } }, /** * Stops event propagation * * @method stopPropagation * @param e {event} The triggering event * @static */ stopPropagation: function(e) { if (e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; } } }; }();
There is an endless amount of other ’stuff’ that could be added to an Event package. However, most of it is not necessary. Here are a few that I use often enough to include in my package:
Bells and Whistles:
- getEvents - returns a collection of events on an element
- getRelatedElem - some mouse events have a related element other than the triggering element
- getTime - the time the event was triggered
- getX - the x position of the event
- getY - the y position of the event
- getXY - the x and y position of the event
- removeAll - removing all events from the page
- removeEventsFromEl - removes all events or a single event type from an element
- control scope of the callback Function
On Friday, I will look at these features and explain how they can be implemented.

[…] my last article (Event Package Part 1), I covered some of the necessary parts of an event package and mentioned some […]
Pingback by Event Package Part 2 | Matt Snider JavaScript Resource — October 24, 2007 @ 1:52 pm