jQuery学习-事件之绑定事件(一)

我们都知道jQuery的事件其思想来源于Dean Edwards的addEvent,通过源码我们知道jQuery在为元素绑定事件时,每种类型的事件(click,blur)时只绑定了一次对应类型的事件处理方法,实际的方法是存在jQuery的缓存系统中的,这样做的好处我就不多说了,绑定方法的函数为add方法,在执行事件的时,通过handers在缓存系统中获取事件列表,然后通过dispatch函数来执行对应的事件。

jQuery.event = {

add: function( elem, types, handler, data, selector ) {
                var tmp, events, t, handleObjIn,
            special, eventHandle, handleObj,
            handlers, type, namespaces, origType,
            elemData = jQuery._data( elem );//从缓存系统中获取对应的事件数据

// 如果不存在事件数据则直接退出
        if ( !elemData ) {
            return;
        }

// Caller can pass in an object of custom data in lieu of the handler
        if ( handler.handler ) {
            handleObjIn = handler;
            handler = handleObjIn.handler;
            selector = handleObjIn.selector;
        }

// 为事件添加标识
        if ( !handler.guid ) {
            handler.guid = jQuery.guid++;
        }

//初始化事件对象数据
        if ( !(events = elemData.events) ) {
            events = elemData.events = {};
        }
                //每种事件类型只绑定一次事件(eventHanle)
        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 !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
                //通过dispatch来触发事件的执行,eventHandle.elem来绑定当前元素,防止this指向错误(attachEvent中this会指向window的bug)
                    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;
        }

//多个事件的绑定
        // Handle multiple events separated by a space
        types = ( types || "" ).match( rnotwhite ) || [ "" ];
        t = types.length;
        while ( t-- ) {
            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;
            }

// If event changes its type, use the special event handlers for the changed type
            special = jQuery.event.special[ type ] || {};

// If selector defined, determine special event api type, otherwise given type
            type = ( selector ? special.delegateType : special.bindType ) || type;

// Update special based on newly reset type
            special = jQuery.event.special[ type ] || {};

//将事件组合成一个事件对象
            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 );

//handlers对应事件类型的事件列表
            if ( !(handlers = events[ type ]) ) {
                handlers = events[ type ] = [];
                handlers.delegateCount = 0;

// Only use addEventListener/attachEvent if the special events handler returns false
                if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
                    //真正绑定事件的地方,只绑定eventHandle
                    if ( elem.addEventListener ) {
                        elem.addEventListener( type, eventHandle, false );

} else if ( elem.attachEvent ) {
                        elem.attachEvent( "on" + type, eventHandle );
                    }
                }
            }
            //特殊事件的处理
            if ( special.add ) {
                special.add.call( elem, handleObj );

if ( !handleObj.handler.guid ) {
                    handleObj.handler.guid = handler.guid;
                }
            }

// 将事件加入事件列表中
            if ( selector ) {
                handlers.splice( handlers.delegateCount++, 0, handleObj );
            } else {
                handlers.push( handleObj );
            }

//表示事件曾经使用过,用于事件优化
            jQuery.event.global[ type ] = true;
        }

// 防止ie内存溢出
        elem = null;
     },
     remove: function( elem, types, handler, selector, mappedTypes ) {
          //为元素移除事件
     },
     trigger: function( event, data, elem, onlyHandlers ) {
         //执行事件
     },
     dispatch: function( event ) {
         //分配事件(在执行方法时执行)
     },
     handlers: function( event, handlers ) {
         //获取缓存系统中对应事件类型的事件列表
     }
}

//其实我们为每种事件绑定的方式是这样的
//通过dispatch来执行对应的事件
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 !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
          jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
      undefined;
}

好了,jQuery的绑定函数原理先介绍到这里。下次继续!一天一点,滴水汇河!

时间: 2024-10-09 03:51:06

jQuery学习-事件之绑定事件(一)的相关文章

jQuery学习-事件之绑定事件(三)

在上一篇<jQuery学习-事件之绑定事件(二)>我们了解了jQuery的dispatch方法,今天我们来学习下handlers 方法: handlers: function( event, handlers ) {         var sel, handleObj, matches, i,             handlerQueue = [],             delegateCount = handlers.delegateCount,             cur =

jQuery学习-事件之绑定事件(二)

在上一篇<jQuery学习-事件之绑定事件(一)>我们了解了jQuery的add方法,今天我们来学习下dispatch方法: dispatch: function( event ) { //这里是修正event对象的属性,处理兼容性问题         event = jQuery.event.fix( event ); var i, ret, handleObj, matched, j,             handlerQueue = [],//事件队列             arg

jQuery学习-事件之绑定事件(七)

今天来说说事件中的handlers方法中的一个片段 1 matches[ sel ] = handleObj.needsContext ?  2     jQuery( sel, this ).index( cur ) >= 0 :  3     jQuery.find( sel, this, null, [ cur ] ).length;  4 /*  5  这是handler是方法中过滤委托的方法.等价于  6 if(handleObj.needsContext){  7     match

jquery事件与绑定事件

1.首先,我们来看一下经常使用的添加事件的方式: <input type="button" id="btn" value="click me!" onclick="shao();" /> <script type="text/javascript"> function shao() { alert("msg is showing!"); } </script

[jquery]高级篇--js绑定事件

参考:  http://www.cnblogs.com/leejersey/p/3545372.html jQuery on()方法是官方推荐的绑定事件的一个方法.$(selector).on(event,childSelector,data,function,map)由此扩展开来的几个以前常见的方法有.bind() 1 $("p").bind("click",function(){ 2 alert("The paragraph was clicked.&

学习指js绑定事件

由于ie中绑定事件的bug,所以产生了用原生的实践操作来模拟事件绑定的方法,跟着李炎恢学的一招. function addEvent(obj, type, fn){ if(obj.addEventListener){ obj.addEventListener(type, fn, false); }else{ if(!obj.events) obj.events = {}: if(!obj.events[type]) {   obj.events[type] = []; if(obj['on'+

jquery 给一个节点绑定事件总结

//给输入框绑定事件   key = $("#key");   key.bind("focus", focusKey).bind("blur", blurKey).bind("change cut input propertychange", searchNode);   key.bind('keydown', function (e){if(e.which == 13){searchNode();}});      setT

Arc gis api for js 学习随笔之绑定事件鼠标动作

1 var map; 2 require(["esri/map", "dojo/domReady!"], function(Map) { 3 map = new Map("GHL", { 4 5 zoom: 3, 6 basemap: "topo", 7 logo:false, 8 9 10 }); 11 dojo.connect(map,"onMouseMove",function(e){ 12 var

jquery移除事件,绑定事件,触发事件

$('.gcddfadf-btn-pay').unbind('click');//移除绑定事件 $('.gcddfadf-btn-pay').bind('click',function(){});//绑定事件$('.gcddfadf-btn-pay').trigger('click');//触发事件 触发自定义事件bind() 方法为被选元素添加一个或多个事件处理程序,并规定事件发生时运行的函数. $('#btn').bind("myclick",function(){....});