提到jQuery的事件,不得不提一下 Dean Edwards大神 addEvent 库,很多流行的类库的基本思想从他那儿借来的。jQuery的事件处理机制吸取了 JavaScript 专家 Dean Edwards 编写的事件处理函数的精华,使得jQuery处理事件绑定的时候相当的可靠。在预留退路(graceful degradation),循序渐进以及非入侵式编程思想方面,jQuery 也做的非常不错。总的来说对于 jQuery 的事件绑定做了 2 大块的处理:
在绑定的时候做了包装处理
在执行的时候有过滤器处理
看看 API 的参数:
.on( events [, selector ] [, data ], handler(eventObject) )
用来绑定一个事件:
var body = $('body') body.on('click','p',function(){ console.log(this) })
用 on 方法给 body 上绑定一个 click 事件,冒泡到 p 元素的时候才出发回调函数,这里大家需要明确一点:
每次在body上点击其实都会触发事件,但是只目标为p元素的情况下才会触发回调的处理函数。通过源码不难发现on方法实质只完成一些参数调整的工作,而实际负责事件绑定的是其内部 jQuery.event.add方法
看看绑定的实际接口on的代码:
on: function(types, selector, data, fn, /*INTERNAL*/ one) { //省略部分代码 return this.each(function() { jQuery.event.add(this, types, fn, data, selector); }); }
jQuery.event.add内部实际上最终还是通过addEventListener绑定的事件
(单击图片可放大)
其中一些变量代码的意思:
现在我们把之前的案例给套一下看看:
var body = document.getElementsByTagName('body') var eventHandle = function() { console.log(this) } body.addEventListener('click', eventHandle, false);
如果是我们自己实现的这个代码是有问题的,我们在body上每次都触发了click事件,但是我们并没有委托的p元素的处理,自然也达不到委托的效果。
eventHandle源码
回到内部绑定的事件句柄 eventHandle ,可想而知 eventHandle 不仅仅只是只是充当一个回调函数的角色,而是一个实现了 EventListener 接口的对象。
if (!(eventHandle = elemData.handle)) { eventHandle = elemData.handle = function(e) { return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply(elem, arguments) : undefined; }; }
可见在 eventHandle 中并没有直接处理回调函数,而是映射到 jQuery.event.dispatch 分派事件处理函数了仅仅只是传入 eventHandle.elem,arguments , 就是 body 元素 与事件对象那么这里有个问题,事件回调的句柄并没有传递过去,后面的代码如何关联?本章的一些地方可能要结合后面的 dispatch 处理才能清理,但是我们还是先看看做了那些处理。
一个简单的流程图:
请验证,完成请求
由于请求次数过多,请先验证,完成再次请求
打开微信扫码自动绑定
绑定后可得到
使用 Ctrl+D 可将课程添加到书签
举报