Common methods of event binding: traditional binding, W3C binding method, and IE binding method . However, what is important for us in actual development is to require a general, cross-browser binding method. If we search on the Internet, we will find many methods. Here are a few more well-known methods:
Before starting the semester, we should discuss what requirements a good addEvent() method should meet:
a. The same event handle that supports the same element can bind multiple listening functions;
b. If the same function is registered multiple times on the same event handle of the same element, all registrations after the first registration will be ignored;
c. This in the function body should point to the node that is processing the event (such as the node that is currently running the event handler);
d. The execution order of the listening function should be executed in the bound order;
e. Do not use event = event || window.event; in the function body to normalize the Event object;
1. The addEvent() function written by John Resig
function addEvent( obj, type, fn ) { if ( obj.attachEvent ) { obj['e'+type+fn] = fn; obj[type+fn] = function(){obj['e'+type+fn]( window.event );} obj.attachEvent( 'on'+type, obj[type+fn] ); } else obj.addEventListener( type, fn, false ); } function removeEvent( obj, type, fn ) { if ( obj.detachEvent ) { obj.detachEvent( 'on'+type, obj[type+fn] ); obj[type+fn] = null; } else obj.removeEventListener( type, fn, false ); }It's really surprising that this function is so simple and easy to understand. Then we still need to look at the five requirements above:
Satisfied with the first point;
I must have been satisfied with the third and fifth points;
For the second point, it is not satisfied because addEventListener() ignores duplicate registration, while attachEvent() does not;
However, the fourth point is not satisfied, because the Dom standard does not determine the order of the time processing functions to call an object, so it should not be taken for granted that they are called in the order of registration.
But this function is still a very good function.
2. The addEvent() function written by Dean Edward
function addEvent(element, type, handler) { if (!handler.$$guid) handler.$$guid = addEvent.guid++; if (!element.events) element.events = {}; var handlers = element.events[type]; if (!handlers) { handlers = element.events[type] = {}; if (element["on" + type]) { handlers[0] = element["on" + type]; } } handlers[handler.$$guid] = handler; element["on" + type] = handleEvent;}addEvent.guid = 1; function removeEvent(element, type, handler) { if (element.events && element.events[type]) { delete element.events[type][handler.$$guid]; }}function handleEvent(event) { var returnValue = true; event = event || fixEvent(window.event); var handlers = this.events[event.type]; for (var i in handlers) { this.$$handleEvent = handlers[i]; if (this.$$handleEvent(event) === false) { returnValue = false; } } return returnValue;}; function fixEvent(event) { event.preventDefault = fixEvent.preventDefault; event.stopPropagation = fixEvent.stopPropagation; return event;};fixEvent.preventDefault = function() { this.returnValue = false;};fixEvent.stopPropagation = function() { this.cancelBubble = true;};This function uses traditional binding methods , so it works in all browsers without causing memory leaks.
But for the 5 points originally proposed, the function only satisfies the first four points. Only the last point is not satisfied, because in JavaScript the order of execution of for/in statements is not specified in the order of assignment, although most of the time is executed in the expected order, so the order of this statement may be different in different JavaScript versions or implementations.
3. Improvement of Dean Edward's addEvent() function
Array.prototype.indexOf = function( obj ){ var result = -1 , length = this.length , i=length - 1; for ( ; i>=0 ; i-- ) { if ( this[i] == obj ) { result = i; break; } } return result;}Array.prototype.contains = function( obj ) { return ( this.indexOf( obj ) >=0 )}Array.prototype.append = function( obj , nodup ) { if ( !(nodup && this.contains( obj )) ) { this[this.length] = obj; }}Array.prototype.remove = function( obj ) { var index = this.indexOf( obj ); if ( !index ) return ; return this.splice( index , 1);};function addEvent(element , type , fun){ if (!element.events) element.events = {}; var handlers = element.events[type]; if (!handlers) { handlers = element.events[type] = []; if(element['on' + type]) { handlers[0] = element['on' + type]; } } handlers.append( fun , true) element['on' + type] = handleEvent;}function removeEvent(element , type , fun) { if (element.events && element.events[type]) { element.events[type].remove(fun); }}function handleEvent(event) { var returnValue = true , i=0; event = event || fixEvent(window.event); var handlers = this.events[event.type] , length = handlers.length; for ( ; i < length ; i++) { if ( handlers[i].call( this , event) === false ){ returnValue = false; } } return returnValue;}function fixEvent(event) { event.preventDefault = fixEvent.preventDefault; event.stopPropagation = fixEvent.stopPropagation; return event;}fixEvent.preventDefault = function() { this.returnValue = false;};fixEvent.stopPropagation = function() { this.cancelBubble = true;};This function is my improvement to Dean Edward's addEvent() function, which fully meets the 5 initial requirements. I hope it will be helpful to everyone's learning. Thank you for your reading.