vapour's blog

27May/10Off

事件监听兼容处理

在事件监听处理方面,IE6-IE8支持attachEvent和detachEvent,而Firefox/Chrome等标准浏览器则支持addEventListener和removeEventListener。并且利用attachEvent方法绑定事件后this指向window,并不是我们期望的被监听元素。我们可以利用prototype的bind函数来解决this指向问题,使用了bind后,就无法再移除事件了。

jRaiser揭秘——事件监听兼容处理中通过增加delegate和getDelegate方法来达到目的,代码如下:

var eventId = 0;
function delegate(elem, eventName, handler) {
   var events = elem.events = elem.events || {}, // 创建事件集合
      id = handler.eventId = handler.eventId || ++eventId; // 生成事件标识
      events[eventName] = events[eventName] || {}; // 创建某种事件的集合

   var trueHandler = function(e) { // 真正被添加的事件处理函数
      handler.call(elem, e);
   };

   events[eventName][id] = trueHandler; // 记下函数的引用
}

function getDelegate(elem, eventName, handler) {
   try { return elem.events[eventName][handler.eventId]; } catch (e) {}
}

function addEvent(elem, eventName, handler) {
   handler = delegate(elem, eventName, handler);
   if (elem.attachEvent) {
      elem.attachEvent(”on” + eventName, handler);
   } else if (elem.addEventListener) {
      elem.addEventListener(eventName, handler, false);
   }
}

function removeEvent(elem, eventName, handler) {
   handler = getDelegate(elem, eventName, handler);
   if (elem.detachEvent) {
      elem.detachEvent(”on” + eventName, handler);
   } else if (elem.removeEventListener) {
      elem.removeEventListener(eventName, handler, false);
   }
}

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 );
}

John Resig的这种方法比较简单,用到的代码比较少,更多的事件代理方法请参考PPK的addEvent() recoding contest

Tagged as: Comments Off
Comments (0) Trackbacks (0)

Sorry, the comment form is closed at this time.

Trackbacks are disabled.