jquery的on

以下见解基于jquery v1.12.4

jquery的on() 方法在被选元素及子元素上添加一个或多个事件处理程序

$(selector).on(event,childSelector,data,function)

一直比较好奇jquery是怎么处理多个参数可以只传几个,且顺序不强制的,遂琢磨了下jquery的on方法

1、 dom结构

<div id="div1">
  <p id="p1" class="p-text">文本1</p>
  <p id="p2" class="p-text">文本2</p>
</div>
复制代码

2、 基本用法

2.1、 最简单的用法
// 点击#div1打印 *点击了*
$('#div1').on('click', function (e) {
  console.log('点击了')
})
复制代码
2.2、 事件委托
// 点击任意p标签打印 *点击了*
$('#div1').on('click', 'p', function (e) {
  console.log('点击了')
})
复制代码
2.3、 参数齐全的事件绑定
// 打印出*123*
$('#div1').on('click', 123, function (e) {
  console.log(e.data)
})
// 点击不会发生任何事情
$('#div1').on('click', '123', function (e) {
  console.log(e.data)
})
复制代码

问题来了,在事件委托那里,我传入的第2个元素是字符串'p',在这里传入字符串'123'点击毫无反应,传入数字123则可以触发。对比on方法的参数顺序,可以发现以上三种例子的顺序都不对应 这就引出了我一开始的问题:jquery是怎么处理多个参数可以只传几个,且顺序不强制的

通过研究一波jquery源码发现,其实原理很简单,就是对传入的参数进行(类型、null、undefined)判断 在jquery内部,会按on方法提供的(约定的)顺序对传入的参数进行判断并转换成其需要的顺序

截取部分代码:

if ( data == null && fn == null ) {

   	// ( types, fn )
   	fn = selector;
   	data = selector = undefined;
   } else if ( fn == null ) {
   	if ( typeof selector === "string" ) {

   		// ( types, selector, fn )
   		fn = data;
   		data = undefined;
   	} else {

   		// ( types, data, fn )
   		fn = data;
   		data = selector;
   		selector = undefined;
   	}
   }
复制代码

源码位置:function on( elem, types, selector, data, fn, one )

3、 批量绑定事件

3.1、 批量绑定相同处理
// 点击、鼠标移入打印*123*
$('#div1').on('click mouseenter', 123, function (e) {
    console.log(e.data)
  })
复制代码
3.2、 批量绑定不同处理
// 点击、鼠标移入、移出打印对应消息
$('#div1').on(
    {
      click: function (e) {console.log('点击:' + e.data)},
      mouseenter: function (e) {console.log('鼠标进入:' + e.data)},
      mouseleave: function (e) {console.log('鼠标移出!')}
    }, 
    123
  )
复制代码

批量绑定不同处理,传入对象形式的参数,内部对参数进行了for...in解构,处理位置:

...
for ( type in types ) {
  on( elem, type, selector, data, types[ type ], one );
}
...
复制代码

两种批量绑定事件最终都从on进入**add: function( elem, types, handler, data, selector ) **,在add方法进行最终的事件添加。 两者最终都会经过add方法的如下代码处理:

...
// Handle multiple events separated by a space
types = ( types || "" ).match( rnotwhite ) || [ "" ]; // types被转为数组,进入while循环遍历
t = types.length;
while ( t-- ) {
...
复制代码

4、 总结

虽然jquery内置了很多方便的处理,但还是有很多种情况考虑不到,比如下面这种情况就无法成功

$('#div1').on(['click', 'mouseenter'], function (e) {
   console.log('点击了')
 })
复制代码

所以,调用方法的时候还是按照约定好的数据结构来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值