达到同一篇涉嫌jQuery中添加事件提供于客户端程序员的接口方法来很多bind/click等,但该实现之核心措施是jQuery.event.add。这首看看那源码,这个add定义如下(省略大部分)

 

add: function( elem, types, handler, data ) {
    if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
        return;
    }

           ...
}

概念了季独参数elem、types、handler和data分别吗HTMLElement、事件类(如click)、事件响应函数、数据。此外,types
可以为空格分开传多风波(“mouseover mouseout”)。handler
有时见面是一个对象(实现live时)。data
最后会挂在扩大后的event对象高达,即当event的性。而event会在handler作为第一单参数将到,这样呢就可以于handler拿到data了。

 

脚详细说明

if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
    return;
}

文本和注释节点直接返回。

 

if ( handler === false ) {
    handler = returnFalse;
} else if ( !handler ) {
    // Fixes bug #7229. Fix recommended by jdalton
    return;
}

参数handler为false时,将handler赋值为returnFalse,returnFalse为一个函数,如下

function returnFalse() {
    return false;
}

jQuery通过handler为false来阻止元素默认行为,停止事件冒泡。这个要组合jQuery.event.handle看。

 

var handleObjIn, handleObj;

if ( handler.handler ) {
    handleObjIn = handler;
    handler = handleObjIn.handler;
}

// Make sure that the function being executed has a unique ID
if ( !handler.guid ) {
    handler.guid = jQuery.guid++;
}

概念变量handleObjIn,handleObj。

handler从字面上看是事件响应(回调)函数,但此间出现handler.handler,让丁加倍感怪异。即什么时候会将handler当一个JS对象传入呢?

大部分时刻传之还是Function类型的,看看源码中jQuery.event.add的调用可窥见jQuery在促成live的早晚会传Object类型。如下

add: function( handleObj ) {
    jQuery.event.add( this,
        liveConvert( handleObj.origType, handleObj.selector ),
        jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
},

此刻会管handleObjIn赋值为所招的JS对象,真正的handler
却是handleObjIn.handler。这话有硌绕,慢慢体会。

 

// Make sure that the function being executed has a unique ID
if ( !handler.guid ) {
    handler.guid = jQuery.guid++;
}

所污染参数handler添加个属性guid,为一个数字,自增的起1起来。即使用jQuery添加事件,会也事件响应函数默认的补充加了性能guid。这个guid再去事件时会见就此到。

// Init the element's event structure
var elemData = jQuery._data( elem );

先取elemData,这里以了前方提到的jQuery._data。第一不行为HTMLElement添加事件是elemData是个缺损对象({})。

 

// If no elemData is found then we must be trying to bind to one of the
// banned noData elements
if ( !elemData ) {
    return;
}

elemData不在则一直归。

 

var events = elemData.events,
    eventHandle = elemData.handle;

定义events,eventHandle。同样第一涂鸦时立即简单个变量都是undefined。

 

if ( !events ) {
    elemData.events = events = {};
}

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;

    };
}

给elemData.events和elemData.handle赋值。

 

// Add elem as a property of the handle function
// This is to prevent a memory leak with non-native events in IE.
eventHandle.elem = elem;

暂存elem到eventHandle,删除事件注册时见面拿其置null,避免有些浏览器中内存泄露。

 

// Handle multiple events separated by a space
// jQuery(...).bind("mouseover mouseout", fn);
types = types.split(" ");

用字符串以空格为切割符转成为屡组。这词使该可同样破上加多单事件,多单事件之handler是千篇一律之。

 

末尾是一个while循环

while ( (type = types[ i++ ]) ) {
    handleObj = handleObjIn ?
        jQuery.extend({}, handleObjIn) :
        { handler: handler, data: data };

      ...

}

循环数组,里面依次拍卖如下

  1. 取得handleObj
  2. 处理事件命名空间,以点号(.)来区别。如果type有硌号,则装有命名空间,否则没有
  3. 让handlerObj添加type,guid属性。这些后续删除事件不时用到
  4. 取得到handlers,special。多数情形下行使addEventListener/attachEvent来填补加波。从变量special可观望对特别之轩然大波如ready,beforeunload及live事件是异常处理的。 
    ready 调用的是jQuery.bindReady,而jQuery.bindReady内部调用的还是是 
    addEventListener/attachEvent。beforeunload则是行使window.onbeforeunload来添加。live是兑现事件代理的,他的拍卖啊是特殊之
  5. 末了吧handleObj添加到数组handles中

jQuery.event.add 的尾声一句,解决IE中内存泄露。

// Nullify elem to prevent memory leaks in IE
elem = null;

 

jQuery事件管理之数据结构,我开了个图。如下

图片 1 

相关文章

网站地图xml地图