代码如下:
var $test = $(document);
function handler1() {
console.log( "handler1" );
$test.off( "click", handler2 );
}
function handler2() {
console.log( "handler2" );
}
$test.on( "click", handler1 );
$test.on( "click", handler2 );
这段代码为什么第一次点击的时候会输出handler1和handler2,handler1中的off起作用了但是仍然会执行一次handler2,原因是什么?
参考jQuery文档
文档里解释的是: Adding or removing event handlers on the current element won't take effect until the next time the event is handled
也许是我英语太渣,我感觉这个地方表述的不是很准确,应该是同一事件的添加或删除在当前处理过程中无效,比如我把两个click改成如下
var $test = $(document);
function handler1() {
console.log( "handler1" );
$test.off( "mouseup", handler2 );
}
function handler2() {
console.log( "handler2" );
}
$test.on( "mousedown", handler1 );
$test.on( "mouseup", handler2 );
那就只会输出handler1,可见在mousedown里off掉mouseup是成功的
回到最开始,为什么同一事件的添加或删除在当前处理过程中无效?(我试着找了找jQuery的源码,比较复杂,放弃了)
还是得从源码开始讲解
先看这里: https://github.com/jquery/jqu...
此处为事件分发的核心代码开始处,可见jquery分发事件时需调用 this.event.handler 求出事件回调的列表,此处 handlerQueue 只是内部事件列表一部分的拷贝,而你用 off 改变的是内部事件列表,对拷贝出的 handlerQueue 自然没有影响。
就像是全部的事件回调函数都存在锅里,当有事件发生时,jquery 会把一部回调拷贝,盛到碗里,然后依次执行碗里的函数。你 off 改变的仅是锅里的函数,碗里的不受影响。