JQuery-1.9.1 source code analysis series (12) screening operations, jquery-1.9.1 source code
In the previous analysis, we also analyzed some filtering operations (For details, refer to). Next we will analyze the main analysis items.
JQuery. fn. find (selector)
Find accepts a parameter expression selector: selector (string), DOM Element, and jQuery object. There are two solutions:
First, if the input parameter is a non-string, the selector is first searched through the jQuery selector, and then the node that contains the matching elements of the current jQuery object is filtered out.
if ( typeof selector !== "string" ) { self = this; return this.pushStack( jQuery( selector ).filter(function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } }) );}
We can see jQuery in the filter condition.Contains(Self [I], this) is the key. this function uses the function in the Sizzle selector. It has Analysis in the Sizzle engine. Click details.
Second, if the selector is a string, call jQuery. find (= Sizzle) for direct processing.
Ret = []; for (I = 0; I <len; I ++) {// The second parameter indicates context jQuery. find (selector, this [I], ret);} // $ (selector, context) to $ (context ). find (selector), requires deduplication and pushStackret = this. pushStack (len> 1? JQuery. unique (ret): ret); ret. selector = (this. selector? This. selector + "": "") + selector; return ret;
JQuery. fn. closest (selectors, context)
The second parameter is optional. Function usedStarting from the current Matching Element, select the first element that matches the specified expression from the upper level.And return it as a jQuery object.
The expressions here include: selector (string), DOM Element, and jQuery object.
The process in the Code is
1. query and save the results in the pos according to the passed parameters.
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?jQuery( selectors, context || this.context ) :0;
2. Traverse every element of the current jQuery object. Starting from this element, select the first ancestor element that matches the specified expression from the upper level.
for ( ; i < l; i++ ) { cur = this[i]; while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { ret.push( cur ); break; } cur = cur.parentNode; }}return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
The parents () and. closest () methods are similar. They all traverse up the DOM tree. However, there is a big difference. closest finds the first one that meets the condition and ends. parents finds all the sets that meet the condition.
JQuery. fn. parent/parents/parentsUntil/next/prev/nextAll/prevAll/nextUntil/prevUntil/siblings/children/contents
The preceding filters are put together for processing. The source code is as follows:
JQuery. each ({parent: function (elem ){...}, Parents: function (elem ){...}, ParentsUntil: function (elem, I, ){...}, Next: function (elem ){...}, Prev: function (elem ){...}, NextAll: function (elem ){...}, PrevAll: function (elem ){...}, NextUntil: function (elem, I, ){...}, PrevUntil: function (elem, I, ){...}, Siblings: function (elem ){...}, Children: function (elem ){...}, Contents: function (elem ){...} }, Function (name, fn) {jQuery. fn [name] = function (until, selector) {var ret = jQuery. map (this, fn, until); // filter... return this. pushStack (ret );};});
We can see that the filtering steps are the same. The map function is used to first substitute each matching element of the current jQuery object into the corresponding matching function (fn) to obtain the result and then perform subsequent filtering.
Let's take a look at the following filtering (we have obtained the alternative seed ret through jQuery. map (this, fn,)
First, not all filtering functions have the until parameter. this parameter is required only for filtering that ends with the Until parameter. For other filtering functions, only the selector parameter is used.
if ( !runtil.test( name ) ) { selector = until;}
Secondly, if there is a selector, filter the previous search result ret through the selector.
if ( selector && typeof selector === "string" ) { ret = jQuery.filter( selector, ret );}
Then, when there are multiple filtering conditions (children/contents/next/prev) in guaranteedUnique, the results obtained by each matching element are stored in the result set ret and do not need to be duplicated. Other filters must be duplicated. Click to view details about jQuery. unique
ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
In addition, if the current jQuery object matches multiple elements, the filtering results using parents/prevUntil/prevAll need to be sorted in reverse order. The reason for inverted order: jQuery. unique uses the sort function Sizzle. uniqueSort In the Sizzle engine. This sort function will be arranged according to the top-level objects in the document to the bottom-layer mode.
if ( this.length > 1 && rparentsprev.test( name ) ) { ret = ret.reverse();}
Finally, return the result of the package.
return this.pushStack( ret );
The Framework Structure of the topic is mentioned above. The following describes the two functions used in the filter matching function: jQuery. dir and jQuery. sibling.
// Keep searching for the dir from the node corresponding to the dir specified by the current element elem, and save these nodes in matched until the cycle ends. Note: The result does not contain the elem node dir: function (elem, dir, until) {var matched = [], cur = elem [dir]; while (cur & cur. nodeType! = 9 & (until = undefined | cur. nodeType! = 1 |! JQuery (cur ). is (until) {if (cur. nodeType = 1) {matched. push (cur) ;}cur = cur [dir];} return matched ;}, // obtain the node set rsibling: function (n, elem) of node n and Its sibling nodes) {var r = []; for (; n = n. nextSibling) {if (n. nodeType = 1 & n! = Elem) {r. push (n) ;}} return r ;}// find the next dir of the current element cur until function sibling (cur, dir) {do {cur = cur [dir];} while (cur & cur. nodeType! = 1); return cur ;}View Code
JQuery. fn. add (selector, context) and jQuery. fn. addBack (selector)
The add function adds an element that matches the specified expression to the current Matching Element and returns it as a jQuery object. Add can receive: selector (string), HTML content (string), DOM Element, jQuery object. Easy to process, directly use the source code
Add: function (selector, context) {var set = typeof selector = "string "? JQuery (selector, context): jQuery. makeArray (selector & selector. nodeType? [Selector]: selector), // Concatenates the result set obtained by the selector expression to the current object. all = jQuery. merge (this. get (), set); // return the new merging result return this. pushStack (jQuery. unique (all ));}
JQuery. fn. add corresponds to jQuery. fn. not. JQuery. fn. not.
JQuery. fn. addBack adds the previously matched elements to the currently matched elements and returns them as new jQuery objects.
addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter(selector) );}jQuery.fn.andSelf = jQuery.fn.addBack;
JQuery. fn. not (selector) and jQuery. fn. filter (selector)
not: function( selector ) { return this.pushStack( winnow(this, selector, false) );}filter: function( selector ) { return this.pushStack( winnow(this, selector, true) );},
Not and filter are the set of operations, not is to filter out items that meet the filtering condition selector in the collection, leaving other items. Filter is an item that meets the filtering condition selector.
The key is the function winnow (elements, qualifier, keep) function. This function is used to perform the same filtering or non-filtering functions. The filter condition qualifier has three types: function, DOM node, and string. Keep: true indicates that the items that meet the filtering conditions are retained. false indicates that the items that do not meet the filtering conditions are retained. Note the source code of winnow as follows:
// Function winnow (elements, qualifier, keep) {// Can't pass null or undefined to indexOf in Firefox 4 // Set to 0 to skip string check qualifier = qualifier | 0; // If the filter condition is a function, filter if (jQuery. isFunction (qualifier) {return jQuery. grep (elements, function (elem, I) {var retVal = !! Qualifier. call (elem, I, elem); return retVal === keep;}); // If the filter condition is DOM-related, filter} else if (qualifier. nodeType) {return jQuery. grep (elements, function (elem) {return (elem === qualifier) === keep ;}); // if the filter condition is string} else if (typeof qualifier = "string") {// filter out the node element var filtered = jQuery in elements. grep (elements, function (elem) {return elem. nodeType = 1;}); // Where isSimple = /^. [^: # \ [\.,] * $/If (isSimple. test (qualifier) {return jQuery. filter (qualifier, filtered ,! Keep);} else {// find the node qualifier that meets the filtering condition qualifier in filtered = jQuery. filter (qualifier, filtered) ;}// filter the elements that meet the filtering conditions in elements: return jQuery. grep (elements, function (elem) {return (jQuery. inArray (elem, qualifier)> = 0) === keep ;});}View Code
JQuery. grep and grep are used here.
JQuery. filter (expr, elems, not) is a low-level api that is used to handle situations where the filter conditions in jQuery. fn. filter are strings.
JQuery. filter: function (expr, elems, not) {if (not) {expr = ": not (" + expr + ")";} // matchesSelector and matches are functions in Sizzle. MatchesSelector is used to determine whether a single element elem meets the expression expr. matches is used to find the return elems. length = 1 in the element set elems that meets the expression expr? JQuery. find. matchesSelector (elems [0], expr )? [Elems [0]: []: jQuery. find. matches (expr, elems );},
JQuery. fn. index (elem)
The index function is actually a set of multi-function functions.
First function: If the elem parameter is not passed, the position of the current jQuery object (the first element of the jQuery object) in all its peers is obtained.
if ( !elem ) { return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;}
Function 2: If the parameter is of the String type, the system regards it as a selector and returns the index position of the current element in the element matched by the selector. If the selector does not match any element or the current element is not within the matched element,-1 is returned.
If (typeof elem = "string") {// search for the specified value in the array jQuery (elem) and return its index value return jQuery. inArray (this [0], jQuery (elem ));}
Third function: if the object is a DOM element or jQuery object, the index position of the element (or the first element in the jQuery object) in the matching element of the current jQuery object is returned.
return jQuery.inArray(elem.jquery ? elem[0] : elem, this );
Other filtering operations will not be analyzed. You can see the source code.
If you think this article is good, click [recommendation] in the lower right corner ]!