JQuery source code analysis-detailed introduction to init, jquery source code init
Init Constructor
Because this function directly matchesjQuery() Parameters.
The source code contains three parameters:
init: function (selector, context, root) { ...}
jQuery(), Null parameter. this will directly return an empty jQuery object, return this.
jQuery( selector [, context ] ) This is a standard and common method. selector represents a css selector, which is usually a string, # id or. class and so on. context indicates the selection range, which can be a DOM or jQuery object.
jQuery( element|elements ) To encapsulate a DOM object or DOM array into a jQuery object.
jQuery( jQuery object|object ) Will wrap the common object or jQuery object in the jQuery object.
jQuery( html [, ownerDocument ] )This method is used to convert an html string into a DOM object and then generate a jQuery object.
jQuery( html, attributes ) Is the same as the previous method, but the methods and attributes in attributes are bound to the generated html DOM, such as class.
jQuery( callback ) This method accepts a callback function, which is equivalent to the window. onload method, but relative.
After the introduction, let's look at the source code.
Init: function (selector, context, root) {var match, elem; // processing: $ (""), $ (null), $ (undefined), $ (false) if (! Selector) {return this;} // rootjQuery = jQuery (document); root = root | rootjQuery; // process HTML strings, including $ ("<div> "), $ ("# id"), $ (". class ") if (typeof selector =" string ") {// This Part of the split is left in the future. // HANDLE: $ (DOMElement)} else if (selector. nodeType) {this [0] = selector; this. length = 1; return this; // HANDLE: $ (function)} else if (jQuery. isFunction (selector) {return root. ready! = Undefined? Root. ready (selector): // Execute immediately if ready is not present selector (jQuery);} return jQuery. makeArray (selector, this );}
Note the following points,root = root || rootjQuery;This parameter is not mentioned in the previous section. This parameter indicates document. The default value is rootjQuery.rootjQuery = jQuery( document ).
We can see that for processing$(DOMElement)Directly treat jQuery as an array,this[0] = DOMElement . In fact, we need to start with the basic structure of jQuery. $('div.span') Then, a jQuery object (this) will get a set of DOM objects, jQuery will add this set of DOM objects as array elements, and give a length. The following is like some chained function operations. If you can only operate on one DOM, such as width and height, you can only operate on the first element. If you can operate on multiple DOM, all DOM operations, such as css ().
The idea of jQuery is as follows, which is a very simple implementation:
JQuery. prototype = {// simple point. Assume that selector uses querySelectorAll init: function (selector) {var ele = document. querySelectorAll (selector); // treats this as an array. each item is a DOM object for (var I = 0; I <ele. length; I ++) {this [I] = ele [I];} this. length = ele. length; return this;}, // If css has only one object, take the first DOM object. // If css has two parameters, set css for each DOM object: function (attr, val) {for (var I = 0; I <this. length; I ++) {if (val = undefined) {if (typeof attr = 'object') {for (var key in attr) {this.css (key, attr [key]) ;}} else if (typeof attr ==== 'string') {return getComputedStyle (this [I]) [attr] ;}} else {this [I]. style [attr] = val ;}}},}
Therefore, for DOMElement processing, directly assign the DOM value to the array and return this.
jQuery.makeArrayIt is a function bound to an array. It is similar to the above principle and will be discussed later.
Before introducing the following content, we will first introduce a regular expression in jQuery that recognizes Html strings,
var rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;rquickExpr.exec('<div>') //["<div>", "<div>", undefined]rquickExpr.exec('<div></div>') //["<div></div>", "<div></div>", undefined]rquickExpr.exec('#id') //["#id", undefined, "id"]rquickExpr.exec('.class') //null
The above series of Regular Expressions exec is only used to describe the result of executing the regular expression rquickExpr. First, if the matching result is found, the length of the result array is 3, if the <div> html is matched, the third element of the array is underfined. If it matches the # id, the second element of the array is underfined. If it does not match, it is null.
There is also a regular expression:
var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );rsingleTag.test('<div></div>') //truersingleTag.test('<div ></div>') //truersingleTag.test('<div class="cl"></div>') //falsersingleTag.test('<div></ddiv>') //false
This regular expression is mainly used to verify the html string to avoid any errors. Exec and regular expressions are not described here.
The following describes how to process HTMl strings:
If (selector [0] === "<" & selector [selector. length-1] = ">" & selector. length >=3) {// The array match = [null, selector, null] matching html is actually forcibly constructed;} else {match = rquickExpr.exe c (selector);} // macth [1] limits html ,! Context pair # id processing if (match & (match [1] |! Context) {// HANDLE: $ (html)-> $ (array) if (match [1]) {// exclude that context is a jQuery object. context = context instanceof jQuery? Context [0]: context; // jQuery. merge is a method specifically designed for jQuery to merge arrays. // jQuery. parseHTML converts html strings to DOM objects jQuery. merge (this, jQuery. parseHTML (match [1], context & context. nodeType? Context. ownerDocument | context: document, true); // HANDLE: $ (html, props) if (rsingleTag. test (match [1]) & jQuery. isPlainObject (context) {for (match in context) {// match if (jQuery. isFunction (this [match]) {this [match] (context [match]); //... and otherwise set as attributes} else {this. attr (match, context [match]) ;}} return this; // process match (1) as underfined! Context} else {elem = document. getElementById (match [2]); if (elem) {// this [0] returns a standard jQuery object this [0] = elem; this. length = 1;} return this;} // handle the general situation. find actually involves Sizzle, and jQuery has included it. The following chapter details // jQuery. find () is a jQuery selector with good performance} else if (! Context | context. jquery) {return (context | root). find (selector); // process! Context} else {// here constructor actually points to jQuery's return this. constructor (context). find (selector );}
About nodeType, this is an attribute of DOM. For more information, see Node. nodeType MDN. The value of nodeType is generally a number, such as 1 indicating DOM and 3 indicating text. You can also use this value to determine whether a DOM element exists, such as context. nodeType.
The entire construction logic, such as the init function, is very clear. For example, the three parameters (selector, context, and root) indicate the selected content, possibly restricted objects, or objects, while root is the defaultjQuery(document) . We still use jQuery's common method, so we are very cautious about processing every variable.
If you carefully read the source code of the above two parts, I also added comments, you should be able to understand the entire process.
The find function is actually a Sizzle, which has been independently developed and used directly in jQuery. The Sizzle selector in jQuery is described in the following chapter. Through the source code, we can find that:
JQuery. find = function Sizzle (){...} jQuery. fn. find = function (selector ){... // reference jQuery. find jQuery. find ()...}
Derivative Functions
The init function still calls a lot of jQuery orjQuery.fnFunction, which is analyzed one by one.
JQuery. merge
Through the name, this function knows what it is used for and merges.
jQuery.merge = function (first, second) { var len = +second.length, j = 0, i = first.length; for (; j < len; j++) { first[i++] = second[j]; } first.length = i; return first;}
In this way, we can merge types that are similar to arrays and have length parameters. I feel that it is mainly for the convenience of merging jQuery objects, because jQuery objects have length.
JQuery. parseHTML
This function is also very interesting, that is, converting a string of HTML strings into DOM objects.
First, the function accepts three parameters. The first parameter data is an html string, and the second parameter is a document object, but browser compatibility must be considered, the third parameter keepScripts is used to delete all script tags in the node, but it is not reflected in parseHTML. It mainly serves buildFragment as a parameter.
The returned object is a DOM array or an empty array.
JQuery. parseHTML = function (data, context, keepScripts) {if (typeof data! = "String") {return [];} // translation parameter if (typeof context = "boolean") {keepScripts = context; context = false;} var base, parsed, scripts; if (! Context) {// The following section indicates creating a document object if (support. createHTMLDocument) {context = document. implementation. createHTMLDocument (""); base = context. createElement ("base"); base. href = document. location. href; context. head. appendChild (base) ;}else {context = document ;}// used to parse parsed. For example, parsed is the processing result of "<div> </div>: ["<div> </div>", "div"] // parsed [1] = "div" parsed = rsingleTag. ex Ec (data); scripts =! KeepScripts & []; // Single tag if (parsed) {return [context. createElement (parsed [1])];} // see the following description for parsed = buildFragment ([data], context, scripts); if (scripts & scripts. length) {jQuery (scripts ). remove ();} return jQuery. merge ([], parsed. childNodes );}
The buildFragment function is mainly used to create a fragment object containing sub-nodes and to add and delete nodes with frequent operations.parsed = buildFragment([data], context, scripts);Create a fragment object and useparsed.childNodes To obtain the HTML corresponding to the data.
JQueyr. makeArray
The function calls in jQuery are actually layer-by-layer. Although sometimes the function is called by the function name, it can be understood, but the logic of thinking is of reference significance.
jQuery.makeArray = function (arr, results) { var ret = results || []; if (arr != null) { if (isArrayLike(Object(arr))) { jQuery.merge(ret, typeof arr === "string" ? [arr] : arr); } else { push.call(ret, arr); } } return ret;}
MakeArray merges the array or string on the left into an array on the right or a new array, which indirectly references jQuery.merge Function.
Next is the isArrayLike function, which may need to consider many factors, such as compatibility with browsers. The following is a long string:
function isArrayLike(obj) { // Support: real iOS 8.2 only (not reproducible in simulator) // `in` check used to prevent JIT error (gh-2145) // hasOwn isn't used here due to false negatives // regarding Nodelist length in IE var length = !!obj && "length" in obj && obj.length, type = jQuery.type(obj); if (type === "function" || jQuery.isWindow(obj)) { return false; } return type === "array" || length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj;}
Summary
This article mainly introduces the important entry functions in jQuery, and will continue to explain Sizzle and the selector in jQuery. If you are interested, please stay tuned to the customer's home. Thank you for your support.