首页 > 代码库 > jQuery事件之:jQuery.event.trigger

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 = http://www.mamicode.com/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缓存数据,根据是否冒泡去执行相应的方法。

 

jQuery事件之:jQuery.event.trigger