jQuery1.6.2源码分析(三)事件处理
针对JQ的源码分析的好的博客已经非常的多了,以下推荐一位哥们的博客:http://nuysoft.iteye.com/blog/1199674。
对于这部分内容,我的这篇博客主要是把一些我自己学习过程中,遇到的一些细节和大家分享以下。
对于.bind() .one()这些方法来说。他们最终都必须通过jQuery.event.add()方法来绑定事件,而在这个add()方法中,用到的很关键的一句代码就是:
var elemData = jQuery._data( elem );
这里用到了JQ缓存方面的知识,不具体讨论,对于这个私有方法_data(elem)来说,首先它传入的就是我们当前触发这个add方法的元素对象(这里要注意,因为live方法也是要调用这个add方法实现的,但live方法都是通过事件委派的原理直接找到根节点,所以这里说的元素对象就不一定是触发live方法的DOM元素了)。我们通过这个方法,找到绑定在这个元素对象上的缓存数据并将这个数据对象赋值给一个变量elemData 。这里最需要注意的就是赋值后的这个变量它是可以直接进行修改的。修改了的结果直接覆盖之前的值,也就是说我如果在别的地方再调用一次jQuery._data(elem) 显示的就是我新修改之后的值。 那么这个数据对象里存储的都是一些什么呢?
这里借用上面分享的博客里的一段代码:
- elemData = {
- events: {
- 'click' : [
- { guid: 5, type: 'click', namespace: '', data: undefined,
- handle: { guid: 5, prototype: {} }
- },
- { ... }
- ],
- 'keypress' : [ ... ]
- },
- handle: { // DOM事件句柄
- elem: elem,
- prototype: {}
- }
- }
if ( !eventHandle ) { elemData.handle = eventHandle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.handle.apply( eventHandle.elem, arguments ) : undefined; }; }
这段代码是定义了要绑定的事件,我们不探究其原理,知道要绑定的事件就是eventHandle就行了。
然后通过原生的事件监听函数绑定这个事件给document.
当冒泡之后触发这个函数时,其调用的就是上面代码里显示的jQuery.event.handle()方法,这个方法里面又调用了一个叫做liveHandler()的方法,在这个方法里 它再一次的调用了之前说道的._data()方法。获取到了我们之前存储的绑定live方法的DOM对象,也就是selector属性里面记录的class id 或者其他参数,通过这个参数,我们再去遍历DOM树获取相应元素。这样就可以确保新添加进来的同ID 或者CLASS 的DOM元素也能绑定上函数,随后将执行函数在这些DOM元素上调用。从而实现了live方法的原理。