javascript事件之:jQuery.event.add事件详解

  我们已经了解过jQuery.event下的方法,回顾一下

jQuery.event = {
    global: {},
    add: function( elem, types, handler, data, selector ) {},
    remove: function( elem, types, handler, selector, mappedTypes ) {},
    trigger: function( event, data, elem, onlyHandlers ) {},
    dispatch: function( event ) {},
    handlers: function( event, handlers ) {},
    props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
    fixHooks: {},
    keyHooks: {
        props: "char charCode key keyCode".split(" "),
        filter: function( event, original ) {}
    },
    mouseHooks: {
        props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
        filter: function( event, original ) {}
    },
    fix: function( event ) {},
    special: {
        load: {
            noBubble: true
        },
        focus: {
            // Fire native event if possible so blur/focus sequence is correct
            trigger: function() {},
            delegateType: "focusin"
        },
        blur: {
            trigger: function() {},
            delegateType: "focusout"
        },
        click: {
            trigger: function() {},
            _default: function( event ) {
                return jQuery.nodeName( event.target, "a" );
            }
        },
        beforeunload: {
            postDispatch: function( event ) {}
        }
    },
    simulate: function( type, elem, event, bubble ) {}
}

今天,我们先来了解jQuery.event.add方法

我们先来看源码

/*  elem: 操作的元素  types: 事件类型  handle: 事件触发的方法  data: 事件触发的方法需要的参数  selector: 委托的元素    调用: 比如我们在jquery.fn.on中的调用  jQuery.fn.extend({    on: function(){      ...      jQuery.event.add( this, types, fn, data, selector );      ...    }  })*/add: function( elem, types, handler, data, selector ) {
    var handleObjIn, eventHandle, tmp,
        events, t, handleObj,
        special, handlers, type, namespaces, origType,     /*     获取绑定在elem上的data缓存      */
        elemData = data_priv.get( elem );
   //不允许出现文本节或者注释节点。但允许出现空对象{}    if ( !elemData ) {
        return;
    }   //这里的handler允许是对象代替handler函数,这里的对象指的是下面的handlerObj。要我说这里有点累赘。干嘛要非得支持这种写法的多样性,增加阅读复杂度。  if ( handler.handler ) {
        handleObjIn = handler;
        handler = handleObjIn.handler;
        selector = handleObjIn.selector;
    }  //给handler添加一个guid属性,确保handler函数有唯一ID,之后的查找或者删除可以使用它
    if ( !handler.guid ) {
        handler.guid = jQuery.guid++;
    }

    // elemData如果没有events属性,给它加上。第一次才会用上
    if ( !(events = elemData.events) ) {
        events = elemData.events = {};
    }  // elemData没有handle属性,给它加上    if ( !(eventHandle = elemData.handle) ) {
        eventHandle = elemData.handle = 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 !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
                jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
                undefined;
        };
        // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
        eventHandle.elem = elem;
    }

    // 处理用空格分开的多事件操作
    types = ( types || "" ).match( core_rnotwhite ) || [""];
    t = types.length;
    while ( t-- ) {     //typenamespace = /^([^.]*)(?:\.(.+)|)$/;
        tmp = rtypenamespace.exec( types[t] ) || [];
        type = origType = tmp[1];
        namespaces = ( tmp[2] || "" ).split( "." ).sort();

        // There *must* be a type, no attaching namespace-only handlers
        if ( !type ) {
            continue;
        }

        // 得到特殊处理的事件类型
        special = jQuery.event.special[ type ] || {};

        // 如果selector有定义,type可能不一样
        type = ( selector ? special.delegateType : special.bindType ) || type;

        // 修正special
        special = jQuery.event.special[ type ] || {};

        // 得到handleObj
        handleObj = jQuery.extend({
            type: type,
            origType: origType,
            data: data,
            handler: handler,
            guid: handler.guid,
            selector: selector,
            needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
            namespace: namespaces.join(".")
        }, handleObjIn );

        // 初始化elemData.events[type]
        if ( !(handlers = events[ type ]) ) {
            handlers = events[ type ] = [];
            handlers.delegateCount = 0;

            // 在没有special.setup或者special.setup返回false时候,对元素绑定事件
            if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
                if ( elem.addEventListener ) {
                    elem.addEventListener( type, eventHandle, false );
                }
            }
        }
    //如果有special.add,执行special.add
        if ( special.add ) {
            special.add.call( elem, handleObj );
       //如果handleObj.handler.guid不存在,吧handler.grid赋值给handleObj.handler.guid
            if ( !handleObj.handler.guid ) {
                handleObj.handler.guid = handler.guid;
            }
        }

        // 把handleObj附加到events[type]数组。对于委托事件,delegateCount++并且添加到数组最前面。否则加到数组后面
        if ( selector ) {
            handlers.splice( handlers.delegateCount++, 0, handleObj );
        } else {
            handlers.push( handleObj );
        }

        // Keep track of which events have ever been used, for event optimization
        jQuery.event.global[ type ] = true;
    }

    // 让elem为空,避免ie内存泄露
    elem = null;
}

上面我们已经对jQuery.event.add的源码做出相应解释。我们再总结一下

这个方法的作用就是对elem身上的data缓存数据进行添加或者修正。之后的大部分操作都是集中在这个数据缓存elemData上操作。

时间: 2024-10-08 20:29:44

javascript事件之:jQuery.event.add事件详解的相关文章

jQuery Event.which 属性详解

jQuery Event.which 属性详解 which属性用于返回触发当前事件时按下的键盘按键或鼠标按钮. 对于键盘和鼠标事件,该属性用于确定你按下的是哪一个键盘按键或鼠标按钮. which属性对DOM原生的event.keyCode和event.charCode进行了标准化. 适用的事件类型主要有键盘事件:keypress.keydown.keyup,以及鼠标事件:mouseup.mousedown. 该属性属于jQuery的Event对象(实例). 语法 jQuery 1.1.3 新增该

jQuery Event.stopImmediatePropagation() 函数详解

stopImmediatePropagation()函数用于阻止剩余的事件处理函数的执行,并防止当前事件在DOM树上冒泡. 根据DOM事件流机制,在元素上触发的大多数事件都会冒泡传递到该元素的所有祖辈元素上,如果这些祖辈元素上也绑定了相应的事件处理函数,就会触发执行这些函数. 使用stopImmediatePropagation()函数可以阻止当前事件向祖辈元素的冒泡传递,也就是说该事件不会触发执行当前元素的任何祖辈元素的任何事件处理函数. 此外,与event.stopPropagation()

jQuery Event.stopPropagation() 函数详解

stopPropagation()函数用于阻止当前事件在DOM树上冒泡. 根据DOM事件流机制,在元素上触发的大多数事件都会冒泡传递到该元素的所有祖辈元素上,如果这些祖辈元素上也绑定了相应的事件处理函数,就会触发执行这些函数. 使用stopPropagation()函数可以阻止当前事件向祖辈元素的冒泡传递,也就是说该事件不会触发执行当前元素的任何祖辈元素的任何事件处理函数. 该函数只阻止事件向祖辈元素的传播,不会阻止该元素自身绑定的其他事件处理函数的函数.event.stopImmediateP

jQuery Event.delegateTarget 属性详解

// 为id为element的元素中的所有span元素绑定click事件 $("#element").on( "click", "span", function(event){ // event.delegateTarget 就是id为element的DOM元素 // this 就是当前触发事件的span元素 alert( event.delegateTarget === this); // false } ); // 为id为element的元

javascript事件之:jQuery.event.remove事件详解

之前已经介绍过jQuery.event.add,现在我们来看看jQuery.event.remove 先上代码 /* elem: 处理的元素 types: 移除的事件 handler: 移除的方法 selector: 委托的元素 mappedTypes: */ remove: function( elem, types, handler, selector, mappedTypes ) { var j, origCount, tmp, events, t, handleObj, special,

jQuery Event add [ 源码分析 ]

/* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { add: function( elem, types, handler, data, selector ) { var elemData, eventHandle, eve

Android-- Android事件机制之二:onTouch详解

Android事件机制之二:onTouch详解 在其中对OntouchEvent中的总结中,不是很具体.本文将主要对onTouch进行总结. onTouch是Android系统中整个事件机制的基础.Android中的其他事件,如onClick.onLongClick等都是以onTouch为基础的. onTouch包括从手指按下到离开手机屏幕的整个过程,在微观形式上,具体表现为action_down.action_move和action_up等过程. onTouch两种主要定义形式如下: (1)在

触碰jQuery:AJAX异步详解

触碰jQuery:AJAX异步详解 传送门:异步编程系列目录…… 示例源码:触碰jQuery:AJAX异步详解.rar AJAX 全称 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML).它并非一种新的技术,而是以下几种原有技术的结合体. 1)   使用CSS和XHTML来表示. 2)   使用DOM模型来交互和动态显示. 3)   使用XMLHttpRequest来和服务器进行异步通信. 4)   使用javascript来绑定和调用.

触碰jQuery:AJAX异步详解(转)

AJAX 全称 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML).它并非一种新的技术,而是以下几种原有技术的结合体. 1)   使用CSS和XHTML来表示. 2)   使用DOM模型来交互和动态显示. 3)   使用XMLHttpRequest来和服务器进行异步通信. 4)   使用javascript来绑定和调用. 通过AJAX异步技术,可以在客户端脚本与web服务器交互数据的过程中使用XMLHttpRequest对象来完成HTTP请