代码如下:
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的源码,比较复杂,放弃了)
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
可以把on可以看成把处理方法加到组件的一个事件处理数组里,off就是从数组里去掉这个方法。当事件触发时,jq就会一次执行事件处理数组里的方法,那么如果事件处理方法里调用了off会怎么样?文档里已经写的很清楚了,在当前事件触发循环里并不会立刻从数组里去掉该处理方法,只有当绑定的事件再触发时才会体现。
感谢大家
问题找到了,原因在于jq内部对于事件的封装处理时,同一类型的事件会添加到同一个数组中,而在触发事件时遍历又是这个数组的一个复制,off没有改变复制的数组,所以导致第一次click的时候输出了hanler2,而对于mousedown和mouseup,因为是不同类型的事件,是封装成两个数组的,所以在mousedown中off掉mouseup是有效的。也许表达的不是很好,贴几行主要的jq源码