/ Published in: JavaScript
`Events.add(element, type, handler)` adds a handler to an element
`Events.remove(element, type, handler)` removes a handler from an element
`Events.getTarget(event)` or `Events.getOrigin(event)` returns the element from which the event originated
`Events.remove(element, type, handler)` removes a handler from an element
`Events.getTarget(event)` or `Events.getOrigin(event)` returns the element from which the event originated
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
//This is based almost entirely on Dean Edwards' code, along with modifications suggested by others in the // comments of his article. //I also added flushEvents() and getTarget(), and associated everything with an Events object. //written by Dean Edwards, 2005 //with input from Tino Zijdel, Diego Perini, Matthias Miller //http://dean.edwards.name/weblog/2005/10/add-event/ //http://therealcrisp.xs4all.nl/upload/addEvent_dean.html //http://dean.edwards.name/weblog/2005/10/add-event2/#comment6264 //http://dean.edwards.name/weblog/2005/10/add-event2/#comment78683 var Events = function() { //***** private properties and methods *****// var undefined; function addEvent(element, type, handler) { if(element.addEventListener) { element.addEventListener(type, handler, false); } else { //assign each event handler a unique ID if(!handler.$$guid) handler.$$guid = addEvent.guid++; //create a hash table of event types for the element if(!element.$$events) element.$$events = {}; //create a hash table of event handlers for each element/event pair var handlers = element.$$events[type]; if(!handlers) { handlers = element.$$events[type] = {}; //store the existing event handler (if there is one) if(element["on" + type]) { handlers[0] = element["on" + type]; } //assign a global event handler to do all the work element["on" + type] = handleEvent; } //store the event handler in the hash table handlers[handler.$$guid] = handler; } } addEvent.guid = 1; //a counter used to create unique IDs for handlers function removeEvent(element, type, handler) { if(element.removeEventListener) { element.removeEventListener(type, handler, false); } else if(element.$$events && element.$$events[type] && handler.$$guid) { //remove the event handler from the hash table delete element.$$events[type][handler.$$guid]; } } //returns the target of an event (make sure to pass the correct event object) function getTarget(event) { if(!event) return null; var target = event.target || event.srcElement || null; if(target && target.nodeType == 3) target = target.parentNode; //it's a text node; defeat Safari bug return target; }; //***helper functions***// function handleEvent(event) { var returnValue = true; //grab the event object (IE uses a global event object) //.parentWindow part is for dealing with multiple windows/frames in IE event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event); //get a reference to the hash table of event handlers var handlers = this.$$events[event.type]; //execute each event handler for(var i in handlers) { //make sure this item is not an inherited property/method if(!Object.prototype[i]) { //make the handler a method of the element so the value of `this` will be correct this.$$handler = handlers[i]; if(this.$$handler(event) === false) { event.preventDefault(); returnValue = false; } } } //`delete` operator doesn't work for DOM elements in IE try{ delete this.$$handler; } catch(e){ this.$$handler = undefined; } return returnValue; } function fixEvent(event) { //add W3C standard event methods event.preventDefault = fixEvent.preventDefault; event.stopPropagation = fixEvent.stopPropagation; return event; } fixEvent.preventDefault = function(){ this.returnValue = false; }; fixEvent.stopPropagation = function(){ this.cancelBubble = true; }; //removes all event handlers from the DOM that were added using the custom solution function flushEvents() { var elems = document.getElementsByTagName("*"); for(var i=0; i<elems.length; i++) { //`delete` operator doesn't work for DOM elements in IE 6 & 7 try{ delete elems[i].$$events; } catch(e){ elems[i].$$events = undefined; } } } //***** initialization *****// //to avoid memory leaks in IE when the page unloads if(!window.removeEventListener) addEvent(window, 'unload', flushEvents); //***** public properties and methods *****// return { add: addEvent, remove: removeEvent, getTarget: getTarget, getOrigin: getTarget }; }(); //initialize Events object