JQuery-1.9.1 source code analysis series (10) Event System Event packaging _ jquery

Source: Internet
Author: User
This article mainly introduces the jQuery-1.9.1 source code analysis series (10) Event System Event packaging related information, the need of friends can refer to the next article to introduce you to the jQuery-1.9.1 source code analysis series (10) Event System Event architecture, this article continues to introduce you to the jquery1.9.1 source code analysis series related knowledge, for more information, see the following.

First, you need to understand that the browser's native events are read-only, which limits jQuery's operations on them. A simple example shows why jQuery has to construct a new event object.

During delegation, node a entrusts Node B to execute the fn function when node a is clicked. When the event bubbles to Node B, the context environment must be correct when the fn is executed, that is, node a executes fn rather than Node B. How to ensure that the Context Environment for executing fn is a node: view the source code (red part)

// Execute ret = (jQuery. event. special [handleObj. origType] | |{}). handle | handleObj. handler). apply (matched. elem, args );

Use apply to replace the context of the execution function with node a (matched. elem ). Another point is that args [0] is the event object event. How can we ensure that the event is an event of node? This is the function of event. currentTarget, which is an important attribute. Therefore, we have performed one step before applying.

event.currentTarget = matched.elem;

Directly change the currentTarget attribute of the event object, which cannot be done in local browser events. Therefore, jQuery event objects are constructed based on local events.

There are two types of events: mouse events and Keyboard Events (you do not know when a touch event can be added ). Take a look at the detailed attributes of the two

  

Some of them are browser-based, not W3C standard. JQuery divides event attributes into three parts

JQuery. event. props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which". split ("")

JQuery. event. keyHooks. props: "char charCode key keyCode". split ("")

JQuery. event. mouseHooks. props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement". split ("")

A. construct a new event object jQuery. event. fix (originalEvent)

Construct a new event object in three steps

Step 1: Use event = new jQuery. event (originalEvent) to construct a new Event object (Click here if you do not understand the role of new ), add isDefaultPrevented, originalEvent, type, timeStamp, and modified tags to create an event (optimized for use to avoid unnecessary processing ). The source code of jQuery. Event (src, props) is as follows:

JQuery. Event = function (src, props) {// Allow instantiation without the 'new' keyword if (! (This instanceof jQuery. event) {return new jQuery. event (src, props);} // src is the Event object if (src & src. type) {this. originalEvent = src; this. type = src. type; // The document for event bubbling may be marked as blocking the occurrence of default events; this function can reflect the correct value of the flag for blocking this. isDefaultPrevented = (src. defaultPrevented | src. returnValue = false | src. getPreventDefault & src. getPreventDefault ())? ReturnTrue: returnFalse; // src is the event type} else {this. type = src;} // Add the explicitly provided features to the event object if (props) {jQuery. extend (this, props);} // create a timestamp if the input event contains more than one this. timeStamp = src & src. timeStamp | jQuery. now (); // The flag event has fixed this [jQuery. expando] = true ;};

The event object created in step 1

  

Step 2: Identify the event type and copy the corresponding attributes from the local originalEvent of the browser.

// Create a copy of The writable event object and format some feature names var I, prop, copy, type = event. type, originalEvent = event, fixHook = this. fixHooks [type]; if (! FixHook) {this. fixHooks [type] = fixHook = // rmouseEvent =/^ (? : Mouse | contextmenu) | click/rmouseEvent. test (type )? This. mouseHooks: // rkeyEvent =/^ key/rkeyEvent. test (type )? This. keyHooks: {};} // obtain the attribute list copy = fixHook. props from the native event? This. props. concat (fixHook. props): this. props ;... // copy all native attributes to the new event. length; while (I --) {prop = copy [I]; event [prop] = originalEvent [prop];}

Step 3: compatible processing of related attributes

// IE <9 corrected the target feature value if (! Event.tar get) {event.tar get = originalEvent. srcElement | document;} // Chrome 23 +, Safari ?, The Target feature value cannot be a text node if (event.tar get. nodeType = 3) {event.tar get = event.tar get. parentNode;} // IE <9. For mouse/Keyboard Events, if metaKey is not defined, set metaKey = false event. metaKey = !! Event. metaKey; // call the hooks filter return fixHook. filter? FixHook. filter (event, originalEvent): event;

The last code is compatible with mouse events and Keyboard Events.

FixHook. filter may be jQuery. event. keyHooks. filter

KeyHooks. filter: function (event, original) {// Add the which feature value to the keyboard event if (event. which = null) {event. which = original. charCode! = Null? Original. charCode: original. keyCode;} return event ;}

Or this jQuery. event. mouseHooks. filter

MouseHooks. filter: function (event, original) {var body, eventDoc, doc, button = original. button, fromElement = original. fromElement; // if the event pageX/Y feature is missing, use the available clientX/Y to calculate if (event. pageX = null & original. clientX! = Null) {eventDoc = event.tar get. ownerDocument | document; doc = eventDoc.doc umentElement; body = eventDoc. body; event. pageX = original. clientX + (doc & doc. scrollLeft | body & body. scrollLeft | 0)-(doc & doc. clientLeft | body & body. clientLeft | 0); event. pageY = original. clientY + (doc & doc. scrollTop | body & body. scrollTop | 0)-(doc & doc. clientTop | body & body. cli EntTop | 0);} // Add the relatedTarget feature if (! Event. relatedTarget & fromElement) {event. relatedTarget = fromElement = event.tar get? Original. toElement: fromElement;} // Add click event which feature value: 1 = left; 2 = middle; 3 = right // remarks: button is not standard, therefore, do not use if (! Event. which & button! = Undefined) {event. which = (button & 1? 1: (button & 2? 3: (button & 4? 2: 0);} return event ;}

The latest event object after the build is as follows (take the mouse event as an example)

  

Native events are saved in originalEvent, and target stores the target node (delegated node and event source). Other information is skipped.

B. Overload event Methods

When building a new event object Event = new jQuery. event (originalEvent), the event inherits the method in jQuery. Event. prototype. Let's take a look at the methods

  

The previous analysis of jQuery. event. prototype overload the stopPropagation method: in addition to calling the event object blocking bubble method, prototype also plays a role in the process of multiple delegated events waiting for processing on the delegated node, one of the events calls the event. stopPropagation () will prevent subsequent event processing. Click here to search for keywords to view

The preventDefault function also plays a similar role. This code is added to the preventDefault function.

this.isPropagationStopped = returnTrue;

In the trigger event function and simulate the bubble simulate function, the isPropagationStopped () function determines whether to perform the default operations on the DOM node. The source code is as follows:

IsImmediatePropagationStopped is a special usage of stopPropagation. isImmediatePropagationStopped directly blocks the current processing and subsequent event processing. stopPropagation then stops the subsequent event processing.

The source code is as follows:

// JQuery. event is bound based on the ECMAScript language specified by the DOM Event // http://www.w.org/TR//WD-DOM-Level--Events-/ecma-script-binding.htmljQuery.Event.prototype = {isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, preventDefault: function. originalEvent; this. isDefaultPrevented = returnTrue; if (! E) {return;} if (e. preventDefault) {e. preventDefault (); // IE support} else {e. returnValue = false ;}}, stopPropagation: function () {var e = this. originalEvent; this. isPropagationStopped = returnTrue; if (! E) {return;} if (e. stopPropagation) {e. stopPropagation ();} // IE supports e. cancelBubble = true;}, stopImmediatePropagation: function () {this. isImmediatePropagationStopped = returnTrue; this. stopPropagation ();}}

The above is the jQuery-1.9.1 source code analysis series (10) Event System Event packaging, hope you like.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.