Jquery v1.4.2 存在自定义事件unbind的bug
时间:2010-11-30 来源:simon4545
这个是jquery中jquery.event.remove中报出来的错误 ,我的控件的代码没有改动,升级了jQuery后就出现了这个问题,这说明jQuery里对事件的解绑出现的问题,我们来分析一下它的代码
// remove generic event handler if no more handlers exist
if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
removeEvent( elem, type, elemData.handle );
}
ret = null;
delete events[ type ];
}
在v1.4.2中新加入了removeEvent这个方法,用来解绑,我们继续跟进下去
var removeEvent = document.removeEventListener ?
function( elem, type, handle ) {
elem.removeEventListener( type, handle, false );
} :
function( elem, type, handle ) {
elem.detachEvent( "on" + type, handle );
};
这里使用了一个三目运算符,用以区分ie,firefox之间对事件的不同方法。但是它忽略了一个问题:如果我们是自定义事件
$(function() {
var obj = $({});
function handler1() {
alert('good');
}
obj.bind('custom1', handler1);
obj.trigger('custom1');
obj.unbind('custom1', handler1);
});
那么无论走进removeEventListener还是detachEvent都会报错。
我们再看一下v.1.4.1的代码
if ( elem.removeEventListener ) {
elem.removeEventListener( type, jQuery.data( elem, "handle" ), false );
} else if ( elem.detachEvent ) {
elem.detachEvent( "on" + type, jQuery.data( elem, "handle" ) );
}
用了else if,而不是else,这样,我们自定义的object,虽然没有removeEventListener和detachEvent方法,但也不会走进if…else…的判断里去,就不会报错。
不过还好resig发现了这个bug,并说明,这个bug会在未来的v.1.4.3中会修补,我在这里提前把修复的代码发给大家先临时用一下,坐等 jQuery 1.4.3吧