1, 下面是JQuery之父推荐的添加移除事件方法。
- /*
- *obj 要绑定事件的对象
- *type 事件类型,指"click", "load", "submit", "mouseover"等
- *fn 函数名
- */
- 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 );
- }
- /*
- *obj 要删除事件的对象
- *type 事件类型,指"click", "load", "submit", "mouseover"等
- *fn 函数名
- */
- 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 );
- }
- //addEvent( document.getElementById('foo'), 'click', doSomething );
2.《Pro JavaScript Techniques》来看,John Resig大大推荐了Dean Edwards的addEvent()方法,而没推荐自己更精简的作品,他这样评价Edwards的addEvent()的:
- 2 , this 关键字可在所有的绑定函数中使用,指向的是当前元素;
- 3 , 中和了所有防止浏览器默认行为和阻止事件冒泡的各种浏览器特定函数;
- 4 , 不管浏览器类型,事件对象总是作为第一个对象传入;
- 5 , 唯一缺点是仅工作在冒泡阶段(因为深入使用事件绑定的传统方法)。
- 6 , addEvent/removeEvent函数如此强大,绝对没有任何理由不在你的代码中使用。
1, 可以在所有浏览器中工作,就算是古老得无任何支持的浏览器;
2, this关键字可在所有的绑定函数中使用,指向的是当前元素;
3, 中和了所有防止浏览器默认行为和阻止事件冒泡的各种浏览器特定函数;
4, 不管浏览器类型,事件对象总是作为第一个对象传入;
5, 唯一缺点是仅工作在冒泡阶段(因为深入使用事件绑定的传统方法)。
6, addEvent/removeEvent函数如此强大,绝对没有任何理由不在你的代码中使用。
而Dean Edwards这样说:
My solution is very different.
* it performs no object detection
* it does not use the addeventListener/attachEvent methods
* it keeps the correct scope (the this keyword)
* it passes the event object correctly
* it is entirely cross-browser (it will probably work on IE4 and NS4)
* and from what I can tell it does not leak memory
下面是Dean Edwards的addEvent/removeEvent函数:
- // http://dean.edwards.name/weblog/2005/10/add-event/
- function addEvent(element, type, handler) {
- if (element.addEventListener) {
- element.addEventListener(type, handler, false );
- } else {
- // 为每一个事件处理函数赋予一个独立的ID
- if (!handler.$$guid) handler.$$guid = addEvent.guid++;
- // 为元素建立一个事件类型的Hash表
- if (!element.events) element.events = {};
- // 为每对元素/事件建立一个事件处理函数的Hash表
- var handlers = element.events[type];
- if (!handlers) {
- handlers = element.events[type] = {};
- // 存储已有的事件处理函数(如果已存在一个)
- if (element[ "on" + type]) {
- handlers[ 0 ] = element[ "on" + type];
- }
- }
- // 在Hash表中存储该事件处理函数
- handlers[handler.$$guid] = handler;
- // 赋予一个全局事件处理函数来处理所有工作
- element[ "on" + type] = handleEvent;
- }
- };
- // 创建独立ID的计数器
- addEvent.guid = 1 ;
- function removeEvent(element, type, handler) {
- if (element.removeEventListener) {
- element.removeEventListener(type, handler, false );
- } else {
- // 从Hash表中删除事件处理函数
- if (element.events && element.events[type]) {
- delete element.events[type][handler.$$guid];
- }
- }
- };
- function handleEvent(event) {
- var returnValue = true ;
- // 获取事件处理对象(IE使用全局的事件对象)
- event = event || fixEvent((( this .ownerDocument || this .document || this ).parentWindow || window).event);
- // 获取事件处理函数Hash表的引用
- var handlers = this .events[event.type];
- // 依次处理每个事件处理函数
- for (var i in handlers) {
- this .$$handleEvent = handlers[i];
- if ( this .$$handleEvent(event) === false ) {
- returnValue = false ;
- }
- }
- return returnValue;
- };
- //增加一些IE事件对象的缺乏的方法
- function fixEvent(event) {
- // 增加W3C标准事件方法
- event.preventDefault = fixEvent.preventDefault;
- event.stopPropagation = fixEvent.stopPropagation;
- return event;
- };
- fixEvent.preventDefault = function() {
- this .returnValue = false ;
- };
- fixEvent.stopPropagation = function() {
- this .cancelBubble = true ;
- };