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