事件代理的实现原理非常简单:利用浏览器中事件的冒泡(event
bubbling)和事件源(target || srcElement)。

少数场景被特意符合利用事件代理,它发如下好处

  1. 要管理的handler更少。
  2. 占据的内存更不见(创建的驻留于内存中的handler少了)。
  3. DOM元素与代码更少的绑定。
  4. DOM变更后(如添加dom节点)无须再绑定事件处理器。

其也时有发生如下不足

  1. 不用所有的风波都能冒泡,如load, change, submit, focus,
    blur(jQuery间接的落实了focus和blur的事件代理)。
  2. 代办元素的handler管理复杂。
  3. 糟糕模拟用户触发事件(jQuery实现了)。

洋洋起来源框架中都投入了风波代理API,比如yui、sencha
touch、gaea等。jQuery的轩然大波代理提供给客户端程序员的生以下几单函数

  • .live 使用document对象代理事件
  • .delegate 根据选择器指定特定的素代理事件
  • .die 解除使用live代理事件的绑定
  • .undelegate 解除使用delegate代理事件的绑定

 如图

jQuery 1

 

以下是delegate的代码

delegate: function( selector, types, data, fn ) {
    return this.live( types, data, fn, selector );
},

可以看它凭借让live,实际上live的季只参数是特别吃delegate用的。并无提供给客户端程序员。live和die一个each调用就特别成了就半只章程。

jQuery.each(["live", "die"], function( i, name ) {
    jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
        var type, i = 0, match, namespaces, preType,
            selector = origSelector || this.selector,
            context = origSelector ? this : jQuery( this.context );
                ...
    };
});

即生成的live和die方法都装有四个参数分别是types, data, fn, origSelector。

types  事件类,如“click”

data   是数(js对象),可以在回调函数中经波目标获得到。

fn      事件handler

origSelector  css选择器,字符串如“#id”

 

此比较奇怪的是第二个参数,因为多数时刻第二单参数我们污染之是函数类型。如下

$('#id').live('click', function(){

});

live内部举行了替换,如

if ( data === false || jQuery.isFunction( data ) ) {
    fn = data || returnFalse;
    data = undefined;
}

假使第二独参数data为false将使returnFalse,returnFalse在前面系列被提到过,是一个函数,里面只一句子:返回false。

若data本身就是是function类型的,那么用将data赋值给fn。既然第二独参数本意就是是函数,干嘛那么困难将第二单参数和第三单参数调换为。不如定义时直换了,如

jQuery.fn[ name ] = function( types, fn, data, origSelector /* Internal Use Only */ )

及时是遗留问题,后续jQuery版本为了跟之前版本参数保持一致。

随之说第四个参数origSelector,这个参数就提供被jQuery库内部采用。简单说她是故来贯彻delegate方法的。live使用document对象做代理,delegate则可运用指定的因素做代办。这里的origSelector就是恃定元素的选择器。

live这段代码

if ( type === "hover" ) {
    types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
    continue;
}

立即是jQuery自己加的事件,即可以如下使用

$('#id').live("hover", fn);

以此用做liveHandler来拘禁,liveHandler中对mouseenter/mouseleave单独做了处理。

 

再探用live时那里面流程是怎么的

  1. live中调用
    jQuery.event.add,此时次单参数是为字符串”live”开头的。会用data,selector,fn等置入第三独参数。

    jQuery.event.add( context[j], “live.” + liveConvert( type, selector ),

     { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
    
  2. 入及jQuery.event.add后,会进到立刻同一句

    special.add.call( elem, handleObj );

special.add 如下

add: function( handleObj ) {

    jQuery.event.add( this,

        liveConvert( handleObj.origType, handleObj.selector ),

        jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );

},

  

会见发现,又是调用jQuery.event.add,即一个递归调用。这是jQuery事件代理部分可比麻烦了解的平片。

live的落实两糟糕调整用jQuery.event.add作用不同。第一蹩脚是往elemData.events备受上加key为live的对象,第二次等是补充加key为真的轩然大波(如click)的靶子。第二次于的handler是个体的liveHandler。

有限差调用后elemData.events 的布局如下(这里因为点击事件,段落P元素示例)

jQuery 2

 

即吃代理元素(如document对象)添加的的确事件是click,但应时会见起live上取fn。知道了live存放数据的构造,那么die的贯彻即哼理解了。

 

相关文章

网站地图xml地图