如今咱們來看看事件機制中的主動觸發,咱們要分析的是jQuery.event.trigger。html
先來看看它在jQ源碼中的調用。node
// 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個。ajax
來看源碼:緩存
/* 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緩存數據,根據是否冒泡去執行相應的方法。app