• 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的绑定函数原理先介绍到这里。下次继续!一天一点,滴水汇河!

  • 相关阅读:
    iOS优化篇之App启动时间优化
    我是如何从一个小哈喽进阶为高级iOS的?
    windows创建bat文件进行截图
    利用certbot-auto生成证书
    修改Linux的环境变量
    常用的Linux命令(好记性不如烂笔头)
    常用的服务端配置文件(Tomcat、MySQL)
    【极致丝滑】利用postcss-px2vw-pv彻底摆脱编辑器插件,灵活可控地转换px至vw
    np.mgrid函数
    快速了解匈牙利算法
  • 原文地址:https://www.cnblogs.com/urols-jiang/p/4305158.html
Copyright © 2020-2023  润新知