Heim >Web-Frontend >js-Tutorial >Jquery 1.9.1-Quellcode-Analysereihen-Filteroperationen
Kommen wir ohne weitere Umschweife direkt zum Thema.
jQuery.fn.find( selector )
find akzeptiert einen Parameterausdruckselektor: Selektor (Zeichenfolge), DOM-Element (Element), jQuery-Objekt. Es gibt zwei Situationen:
Die erste: Wenn der eingehende Parameter kein String ist, suchen Sie zuerst den Selektor über den jQuery-Selektor und filtern Sie dann die im aktuellen enthaltenen übereinstimmenden Elemente heraus jQuery-Objekt. Der Knoten des Elements.
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; } } }) ); }
Sie können sehen, dass jQuery.contains( self[ i ], this ) der Schlüssel in der Filterbedingung ist. Diese Funktion verwendet die Funktion im Sizzle-Selektor . Es gibt eine Analyse in der Sizzle-Engine, klicken Sie für Details.
Zweitens: Wenn der Selektor ein String ist, rufen Sie jQuery.find (= Sizzle) auf, um ihn direkt zu verarbeiten
ret = []; for ( i = 0; i < len; i++ ) { //第二个参数是表示context jQuery.find( selector, this[ i ], ret ); } //$( selector, context )变成$( context ).find( selector ),需要去重和pushStack ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); ret.selector = ( this.selector ? this.selector + " " : "" ) + selector; return ret;
jQuery.fn.closest( selectors, context )
Der zweite Parameter ist optional. Die Funktion wird verwendet, um das erste Element auszuwählen, das dem angegebenen Ausdruck entspricht, beginnend mit dem aktuell übereinstimmenden Element, und es in Form eines jQuery-Objekts zurückzugeben.
Die Ausdrücke hier umfassen: Selektor (String), DOM-Element (Element) und jQuery-Objekt.
Die Verarbeitungsschritte im Code sind
1. Fragen Sie zunächst die Ergebnisse gemäß den übergebenen Parametern ab und speichern Sie sie in pos.
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? jQuery( selectors, context || this.context ) : 0;
2. Durchlaufen Sie jedes Element des aktuellen jQuery-Objekts. Wählen Sie ausgehend von diesem Element Schritt für Schritt das erste Vorgängerelement aus, das dem angegebenen Ausdruck entspricht.
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 );
Die Methoden parent() und .closest() ähneln sich darin, dass sie beide den DOM-Baum nach oben durchlaufen. Aber der Unterschied ist auch sehr groß: „Am nächsten“ findet das erste, das die Bedingungen erfüllt, und „Eltern“ findet alle Sets, die die Bedingungen erfüllen.
jQuery.fn. parent/ parent/ parentUntil/ next/ prev/ nextAll/ prevAll/ nextUntil/ prevUntil/ siblings/ children/ ausführliche Erklärung des Inhalts
Die oben genannten Gruppen Wenn die Anzahl der Filter zusammen verarbeitet wird, lautet der Quellcode wie folgt:
jQuery.each({ parent: function( elem ) {…}, parents: function( elem ) {…}, parentsUntil: function( elem, i, until ) {…}, next: function( elem ) {…}, prev: function( elem ) {…}, nextAll: function( elem ) {…}, prevAll: function( elem ) {…}, nextUntil: function( elem, i, until ) {…}, prevUntil: function( elem, i, until ) {…}, 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 ); //过滤 ... return this.pushStack( ret ); }; });
Es ist ersichtlich, dass diese Filterschritte konsistent sind. Jedes übereinstimmende Element des aktuellen jQuery-Objekts wird zunächst über die Kartenfunktion in die entsprechende Übereinstimmungsfunktion (fn) eingesetzt, um das Ergebnis zu erhalten, und anschließend wird eine anschließende Filterung durchgeführt.
Werfen wir zunächst einen Blick auf die nachfolgende Filterung (der alternative Startwert ret wurde über jQuery.map( this, fn, Until ) erhalten)
Erstens verfügen nicht alle Filterfunktionen über diese Funktion bis Dieser Parameter ist nur für einige Filter erforderlich, die mit „Until“ enden. Andere Filter verfügen nur über den Selektorparameter.
if ( !runtil.test( name ) ) { selector = until; }
Zweitens, wenn es einen Selektor gibt, filtern Sie die vorherigen Suchergebnisse durch den Selektor ret
if ( selector && typeof selector === "string" ) { ret = jQuery.filter( selector, ret ); }
Dann garantierteedUnique Es gibt mehrere Filterbedingungen (untergeordnete Elemente/Inhalte/nächste/vorherige) Wenn die Anzahl der vom aktuellen jQuery-Objekt übereinstimmenden Elemente mehrfach ist, werden die durch jedes übereinstimmende Element erhaltenen Ergebnisse in der Ergebnismenge ret gespeichert, und es ist nicht erforderlich, das Gewicht zu entfernen . Es müssen weitere Untersuchungen durchgeführt werden. Klicken Sie hier, um die detaillierte Erklärung der jQuery.unique-Methode anzuzeigen
ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
Darüber hinaus müssen folgende Sonderfälle behandelt werden: Wenn mehrere Elemente mit der aktuellen jQuery übereinstimmen Objekt, verwenden Sie parent /prevUntil / prevAll Die Ergebnisse dieser drei Filter müssen in umgekehrter Reihenfolge sortiert werden. Der Grund für die Notwendigkeit der umgekehrten Reihenfolge: jQuery.unique verwendet die Sortierfunktion Sizzle .uniqueSort in der Sizzle-Engine. Diese Sortierfunktion ordnet Objekte vom obersten Objekt bis zum untersten Objekt im Dokument.
if ( this.length > 1 && rparentsprev.test( name ) ) { ret = ret.reverse(); }
Zum Schluss das verpackte Ergebnis zurückgeben
return this.pushStack( ret );
Die oben erwähnte Rahmenstruktur des Themas, lassen Sie uns darüber sprechen Gehen Sie für die beiden Funktionen jQuery.dir und jQuery.sibling, die in der Gruppenfilter-Matching-Funktion verwendet werden, direkt zum Quellcode
// Suchen Sie nach dem Verzeichnis, beginnend mit dem Knoten, der dem durch das aktuelle Element elem angegebenen Verzeichnis entspricht, und speichern Sie diese Knoten in abgeglichen, bis die Schleife endet. Hinweis: Das Ergebnis enthält keine Elem-Knoten
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; }, //获取节点n及其兄弟节点中非elem的节点集合r sibling: function( n, elem ) { var r = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { r.push( n ); } } return r; } //找到当前元素cur的下一个dir为止 function sibling( cur, dir ) { do { cur = cur[ dir ]; } while ( cur && cur.nodeType !== 1 ); return cur; }
jQuery.fn.add( selector, context )和jQuery.fn. addBack( selector )
Die Add-Funktion fügt einen angegebenen Ausdruck zum aktuellen Abgleich hinzu Elementelement der Formel und als jQuery-Objekt zurückgegeben. add kann empfangen: Selektor (String), HTML-Inhalt (String), DOM-Element (Element) und jQuery-Objekt. Die Verarbeitung ist relativ einfach. Gehen Sie einfach zum Quellcode
add: function( selector, context ) { var set = typeof selector === "string" ? jQuery( selector, context ) : jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), //把selector表达式获取的结果集拼接到当前对象上 all = jQuery.merge( this.get(), set ); //返回新的拼接结果 return this.pushStack( jQuery.unique(all) ); } jQuery.fn.add和jQuery.fn.not相对应。jQuery.fn.not后面再说。 jQuery.fn.addBack将之前匹配的元素加入到当前匹配的元素中,并以新的jQuery对象的形式返回。 addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter(selector) ); } jQuery.fn.andSelf = jQuery.fn.addBack; jQuery.fn.not( selector )和jQuery.fn.filter( selector ) not: function( selector ) { return this.pushStack( winnow(this, selector, false) ); } filter: function( selector ) { return this.pushStack( winnow(this, selector, true) ); },
Nicht und Filter sind beide Sammlungen des Vorgangs selbst, nicht die Elemente in der Sammlung selbst herauszufiltern Erfüllen Sie die Filterbedingungsauswahl und lassen Sie andere Elemente übrig. Der Filter dient dazu, Elemente zu hinterlassen, die die Filterbedingungsauswahl erfüllen.
Der Schlüssel ist die Funktion winnow(elements, qualifier, keep) Funktion. Die Funktion dieser Funktion besteht darin, dieselbe Filter- oder Nichtfilterfunktion auszuführen. Es gibt drei Arten von Filterbedingungsqualifizierern: Funktionen, DOM-Knoten und Zeichenfolgen. keep: true bedeutet, Elemente zu behalten, die die Filterbedingungen erfüllen, false bedeutet, Elemente zu behalten, die die Filterbedingungen nicht erfüllen.
Die Quellcode-Kommentare von Winnow lauten wie folgt
//执行相同的过滤或者不过滤的功能 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 ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); return retVal === keep; }); //如果过滤条件是DOM相关类型,通过比较节点是否相同来过滤 } else if ( qualifier.nodeType ) { return jQuery.grep(elements, function( elem ) { return ( elem === qualifier ) === keep; }); //如果过滤条件是字符串 } else if ( typeof qualifier === "string" ) { //过滤出elements中的节点元素 var filtered = jQuery.grep(elements, function( elem ) { return elem.nodeType === 1; }); // 其中isSimple = /^.[^:#\[\.,]*$/ if ( isSimple.test( qualifier ) ) { return jQuery.filter(qualifier, filtered, !keep); } else { //查找filtered中满足筛选条件qualifier的节点 qualifier = jQuery.filter( qualifier, filtered ); } } //过滤出elements中满足过滤条件的元素 return jQuery.grep(elements, function( elem ) { return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; }); }
jQuery.grep wird verwendet. Klicken Sie hier für eine detaillierte Erklärung von grep.
jQuery.filter(expr, elems, not) Diese Low-Level-API wird speziell für den Fall verwendet, dass die Filterbedingung in jQuery.fn.filter eine Zeichenfolge ist.
jQuery.filter: function( expr, elems, not ) { if ( not ) { expr = ":not(" + expr + ")"; } //其中matchesSelector和matches是Sizzle中的函数。matchesSelector是判断单个元素elem是否满足表达式expr,matches是查找元素集合elems中满足表达式expr的项 return elems.length === 1 ? jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : jQuery.find.matches(expr, elems); }, jQuery.fn.index( elem )
index函数实际上是一个多功能函数的集合。
第一个功能:不传递elem参数,则表示取当前jQuery对象(jQuery对象的第一个元素)在其所有同辈元素中的位置。
if ( !elem ) { return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; }
第二个功能:如果参数为String类型则将其视作选择器,返回当前元素在选择器所匹配的元素中的索引位置。如果该选择器不匹配任何元素或者当前元素不在匹配到的元素内,则返回-1。
if ( typeof elem === "string" ) { //在数组jQuery( elem )中搜索指定的值,并返回其索引值 return jQuery.inArray( this[0], jQuery( elem ) ); }
第三个功能:如果object为DOM元素或jQuery对象,则返回该元素(或该jQuery对象中的第一个元素)在当前jQuery对象所匹配的元素中的索引位置。
return jQuery.inArray(elem.jquery ? elem[0] : elem, this );
其他的筛选处理就不分析了。看源码即可明白。
【相关教程推荐】
1. JavaScript视频教程
2. JavaScript在线手册
3. bootstrap教程