jQuery中on、off的问题

本文探讨了jQuery中的on()和off()方法如何工作,通过实例解释了为何在同一事件处理过程中添加或移除监听器不起作用的原因,并深入分析了jQuery源码中的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先基本的科普知识 .on() and .off()方法是jQuery1.7正式版发布

代码示例1

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

第一次点击document,会在控制台看到

handler1
handler2

代码示例2

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

第一次点击document,会在控制台看到

handler1

问题来了,为什么同一事件的添加或删除在当前处理过程中无效?

查看Jq源码:

//获取触发的事件的数组,在上面的代码中触发click时这个数组中是有两个值的,而触发mousedown时是只有一个值的,这个值是内部封装的一个handleObj对象
handlers = ((jQuery._data(this, "events") || {})[event.type] || [])

...

//之后会把这个handlers数组根据是否委托来slice(也是这个地方复制了handlers,导致click中的off第一次点击的时候无效),然后添加到数组handlerQueue中
handlerQueue.push({ elem: this, matches: handlers.slice(delegateCount) })

...
//最后触发的时候是遍历handlerQueue中的matches来执行
 for (i = 0; i < handlerQueue.length && !event.isPropagationStopped() ; i++) {
                matched = handlerQueue[i];
                event.currentTarget = matched.elem;

                for (j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped() ; j++) {
                    ...
                    }
}

原因在于jq内部对于事件的封装处理时,同一类型的事件会添加到同一个数组中,而在触发事件时遍历又是这个数组的一个复制,off没有改变复制的数组,所以导致第一次click的时候输出了hanler2,而对于mousedown和mouseup,因为是不同类型的事件,是封装成两个数组的,所以在mousedown中off掉mouseup是有效的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值