• jQuery事件之:jQuery.event.trigger


      现在我们来看看事件机制中的主动触发,我们要分析的是jQuery.event.trigger。

      先来看看它在jQ源码中的调用。

     // 1, 在jQuery.event.simulate中
     jQuery.event.simulate = function(){
        ...
        if ( bubble ) {
            jQuery.event.trigger( e, null, elem );
        }
        ...
     }
    // 2, 事件的实例方法中
     jQuery.fn.extend({
        trigger: function( type, data ) {
            return this.each(function() {
                jQuery.event.trigger( type, data, this );
            });
        },
        triggerHandler: function( type, data ) {
            var elem = this[0];
            if ( elem ) {
                return jQuery.event.trigger( type, data, elem, true );
            }
        }
     })
    // 3, ajax中也有主动触发
     jQuery.event.trigger("ajaxStart");
     jQuery.event.trigger("ajaxStop");
     

      看到其调用,我们能猜出其参数,有4个。

      来看源码:

    /*
    type: 事件的类型
    data: 事件传递的参数
    elem: 绑定事件的元素
    onlyHandler: 是否冒泡和触发默认事件
    */
    trigger: function( event, data, elem, onlyHandlers ) {
        var i, cur, tmp, bubbleType, ontype, handle, special,
            eventPath = [ elem || document ],
            //event支持对象的写法, 比如{"type": "click"}
            type = core_hasOwn.call( event, "type" ) ? event.type : event,
            namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
    
        cur = tmp = elem = elem || document;
    
        // 如果是文本节点和注释节点,return;
        if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
            return;
        }
    
        // focus/blur morphs to focusin/out; ensure we're not firing them right now
        if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
            return;
        }
        //如果有命名空间,重新得到type和namepaces
        if ( type.indexOf(".") >= 0 ) {
            // Namespaced trigger; create a regexp to match event type in handle()
            namespaces = type.split(".");
            type = namespaces.shift();
            namespaces.sort();
        }
        // 得到ontype。&&的 用法, 如果type不含有':', 比如type='click', ontype = 'onclick', 否则ontype = false
        ontype = type.indexOf(":") < 0 && "on" + type;
    
        // 构建或得到event对象
        event = event[ jQuery.expando ] ?
            event :
            new jQuery.Event( type, typeof event === "object" && event );
    
        // 以下都是构建event实例方法
        event.isTrigger = onlyHandlers ? 2 : 3;
        event.namespace = namespaces.join(".");
        event.namespace_re = event.namespace ?
            new RegExp( "(^|\.)" + namespaces.join("\.(?:.*\.|)") + "(\.|$)" ) :
            null;
        event.result = undefined;
        if ( !event.target ) {
            event.target = elem;
        }
    
        // 初始化data
        data = data == null ?
            [ event ] :
            jQuery.makeArray( data, [ event ] );
    
        // Allow special events to draw outside the lines
        special = jQuery.event.special[ type ] || {};
        if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
            return;
        }
    
        // Determine event propagation path in advance, per W3C events spec (#9951)
        // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
        // 得到冒泡的路径eventPath, 如,[div, h3, body, html, Document]
        if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
    
            bubbleType = special.delegateType || type;
            if ( !rfocusMorph.test( bubbleType + type ) ) {
                cur = cur.parentNode;
            }
            for ( ; cur; cur = cur.parentNode ) {
                eventPath.push( cur );
                tmp = cur;
            }
    
            // Only add window if we got to document (e.g., not plain obj or detached DOM)
            if ( tmp === (elem.ownerDocument || document) ) {
                eventPath.push( tmp.defaultView || tmp.parentWindow || window );
            }
        }
    
        // Fire handlers on the event path
        i = 0;
        while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
    
            event.type = i > 1 ?
                bubbleType :
                special.bindType || type;
    
            //得到父元素的handle
            handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
            // 存在则执行handle
            if ( handle ) {
                handle.apply( cur, data );
            }
    
            // 调用的是元素绑定的时间
            handle = ontype && cur[ ontype ];
            if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
                event.preventDefault();
            }
        }
        event.type = type;
        
        // If nobody prevented the default action, do it now
        if ( !onlyHandlers && !event.isDefaultPrevented() ) {
    
            if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
                jQuery.acceptData( elem ) ) {
                if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
    
                    // 得到行内绑定的方法
                    tmp = elem[ ontype ];
                    //对行内绑定到的方法制空
                    if ( tmp ) {
                        elem[ ontype ] = null;
                    }
    
                    // 执行
                    jQuery.event.triggered = type;
                    elem[ type ]();
                    jQuery.event.triggered = undefined;
                    //重新绑定回去
                    if ( tmp ) {
                        elem[ ontype ] = tmp;
                    }
                }
            }
        }
        return event.result;
    },

    主要流程就是取得data缓存数据,根据是否冒泡去执行相应的方法。

  • 相关阅读:
    3Dtouch 的实际应用详解(tableView中的应用)
    使用UIScrollView的zoomscale实现图片捏合放大
    SVN命令使用详解
    参数传递
    cookie文件路径
    XML和HTML之间的差异
    cssSelector元素定位方法
    如何调用一个数据完整的firefox浏览器
    Android生命周期详解
    android 利用countDownLatch实现主线程与子线程之间的同步
  • 原文地址:https://www.cnblogs.com/pfzeng/p/4193797.html
Copyright © 2020-2023  润新知