JQuery Event add [Source Code Analysis]
/** Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards 'addevent library for example of the ideas. */jQuery. event = {add: function (elem, types, handler, data, selector) {var elemData, eventHandle, events, t, tns, type, namespaces, handleObj, handleObjIn, quick, handlers, special; // Don't attach events to noData or text/comment nodes (allow plain objects Tho) if (elem. nodeType = 3 | elem. nodeType = 8 |! Types |! Handler |! (ElemData = jQuery. _ data (elem) {return;} // Caller can pass in an object of custom data in lieu of the handler // I have never understood why I should do this before, the reason is that handler can be a function, that is, the event method we usually call to bind // it can also be an event object, that is, handleObj, if it is inside jQuery, it can pass an event object over if (handler. handler) {handleObjIn = handler; handler = handleObjIn. handler; selector = handleObjIn. selector;} // Make sure that the handler has a unique ID, use D to find/remove it later // assign guidif (! Handler. guid) {handler. guid = jQuery. guid ++;} // Init the element's event structure and main handler, if this is the first // from the cache system, obtain the events array events = elemData from the cache event object. events; if (! Events) {elemData. events = events ={};} // The primary listening function. the only method bound to the dom element calls the dispatch allocation event eventHandle = elemData. handle; if (! EventHandle) {elemData. handle = eventHandle = function (e) {// Discard the second event of a jQuery. event. trigger () and // when an event is called after a page has unloaded // This mainly prevents secondary bubbling when trigger is manually triggered. Here, there will be a simulated bubble event in the trigger, // mainly for events that cannot be bubbling, such as: focus, you can only simulate the bubble event // if it has already been bubbling, you do not need to execute it again here. Return typeof jQuery! = "Undefined "&&(! E | jQuery. event. triggered! = E. type )? 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 // the eventHandle mainly addresses ie memory problems. elem = elem;} // Handle multiple events separated by a space // jQuery (...). bind ("mouseover mouseout", fn); // cut multiple event combinations types = jQuery. trim (hoverHack (types )). split (""); for (t = 0; t <types. length; t ++ ){/ /Use regular expressions to cut the namespace // rtypenamespace =/^ ([^ \.] *)? (?: \. (. + ))? $/, // For example, click. namespace, hover. namespace // ==> ["click. namespace "," click "," namespace ", index: 0, input:" click. namespace "] tns = rtypenamespace.exe c (types [t]) | []; type = tns [1]; namespaces = (tns [2] | ""). split (". "). sort (); // If event changes its type, use the special event handlers for the changed type // here we mainly fix the event to see If there are definitions in special, if so, replace the event type in special with some native events, and there is a compatibility problem with the browser, so you need to replace the spe Cial = jQuery. event. special [type] | {}; // If selector defined, determine special event api type, otherwise given type // The selector here is a proxy event. If selector exists, then there will be a bubble event // For delegateType, it is mainly used to replace events that cannot be bubble native, such as: focus => focusin // If native events have no problems with bubble, check whether the binding type needs to be fixed, for example, mouseover ==> mouseenter type = (selector? Special. delegateType: special. bindType) | type; // Update special based on newly reset typespecial = jQuery. event. special [type] | |{}; // handleObj is passed to all event handlershandleObj = jQuery. extend ({type: type, origType: tns [1], data: data, handler: handler, guid: handler. guid, selector: selector, quick: selector & quickParse (selector), namespace: namespaces. join (". ")}, handleObjIn); // Init The event handler queue if we're re the firsthandlers = events [type]; if (! Handlers) {handlers = events [type] = []; handlers. delegateCount = 0; // Only use addEventListener/attachEvent if the special events handler returns falseif (! Special. setup | special. setup. call (elem, data, namespaces, eventHandle) === false) {// Bind the global event handler to the elementif (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 ;}// Add to the element's handler list, delegates in frontif (selector) {handlers. splice (handlers. delegateCount ++, 0, handleObj);} else {handlers. push (handleObj);} // Keep track of which events have ever been used, for event optimizationjQuery. event. global [type] = true;} // Nullify elem to prevent memory leaks in IEelem = null ;}