Maison >interface Web >js tutoriel >Opérations de filtrage des séries d'analyses de code source Jquery 1.9.1
Sans plus attendre, passons directement au sujet.
jQuery.fn.find( selector )
find accepte un sélecteur d'expression de paramètre : sélecteur (chaîne), élément DOM (Element), objet jQuery. Il est géré dans deux situations :
La première, si le paramètre entrant n'est pas une chaîne, recherchez d'abord le sélecteur via le sélecteur jQuery, puis filtrez les éléments correspondants contenus dans le courant Objet jQuery. Le nœud de l'élément.
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; } } }) ); }
Vous pouvez voir que jQuery.contains( self[ i ], this ) est la clé dans la condition de filtre. Cette fonction utilise la fonction du sélecteur Sizzle. . Il y a une analyse dans le moteur Sizzle, cliquez pour plus de détails.
Deuxièmement, si le sélecteur est une chaîne, appelez jQuery.find (= Sizzle) pour le traiter directement
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 )
Le deuxième paramètre est facultatif. La fonction est utilisée pour sélectionner le premier élément qui correspond à l'expression spécifiée, en commençant par l'élément correspondant actuel et en le renvoyant sous la forme d'un objet jQuery.
Les expressions ici incluent : le sélecteur (chaîne), l'élément DOM (Element) et l'objet jQuery.
Les étapes de traitement dans le code sont
1. Interrogez d'abord les résultats en fonction des paramètres transmis et enregistrez-les en pos.
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? jQuery( selectors, context || this.context ) : 0;
2. Parcourez chaque élément de l'objet jQuery actuel. À partir de cet élément, sélectionnez étape par étape le premier élément ancêtre qui correspond à l'expression spécifiée.
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 );
Les méthodes parents() et .closest() sont similaires dans le sens où elles parcourent toutes les deux l'arborescence DOM. Mais la différence est également très grande : le plus proche trouve le premier qui remplit les conditions et y met fin ; les parents trouvent tous les ensembles qui remplissent les conditions.
jQuery.fn. parent/ parents/ parentsUntil/ next/ prev/ nextAll/ prevAll/ nextUntil/ prevUntil/ siblings/ children/ contents explication détaillée
Les groupes ci-dessus des filtres sont traités ensemble, le code source est le suivant
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 ); }; });
On voit que ces étapes de filtrage sont cohérentes. Chaque élément correspondant de l'objet jQuery actuel est d'abord remplacé dans la fonction de correspondance correspondante (fn) via la fonction map pour obtenir le résultat, puis un filtrage ultérieur est effectué.
Jetons d'abord un coup d'œil au filtrage ultérieur (le seed ret alternatif a été obtenu via jQuery.map( this, fn, Until ))
Tout d'abord, toutes les fonctions de filtrage n'ont pas jusqu'à Ce paramètre n'est requis que pour plusieurs filtres se terminant par Jusqu'à. Les autres filtres n'ont que le paramètre sélecteur.
if ( !runtil.test( name ) ) { selector = until; }
Deuxièmement, s'il y a un sélecteur, filtrez les résultats de recherche précédents via le sélecteur ret
if ( selector && typeof selector === "string" ) { ret = jQuery.filter( selector, ret ); }
Ensuite, garantieedUnique Il existe plusieurs conditions de filtrage (children/contents/next/prev). Lorsque le nombre d'éléments correspondant à l'objet jQuery actuel est multiple, les résultats obtenus via chaque élément correspondant sont enregistrés dans le jeu de résultats ret, et il n'est pas nécessaire de supprimer le poids. . D'autres dépistages doivent être effectués. Cliquez pour voir l'explication détaillée de la méthode jQuery.unique
ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
De plus, les cas particuliers qui doivent être traités sont : S'il y a plusieurs éléments correspondant au jQuery actuel objet, utilisez parents /prevUntil / prevAll Les résultats de ces trois filtres doivent être triés dans l'ordre inverse. La raison de la nécessité de l'ordre inverse : jQuery.unique utilise la fonction de tri Sizzle .uniqueSort dans le moteur Sizzle. Cette fonction de tri organise les objets de l'objet le plus haut à l'objet le plus bas dans le document.
if ( this.length > 1 && rparentsprev.test( name ) ) { ret = ret.reverse(); }
Enfin, renvoyez le résultat packagé
return this.pushStack( ret );
Ce qui précède a mentionné la structure du thème, parlons-en Pour les deux fonctions jQuery.dir et jQuery.sibling utilisées dans la fonction de correspondance de filtre de groupe, allez directement dans le code source
// Rechercher le répertoire à partir du nœud correspondant au répertoire spécifié par l'élément courant elem, et sauvegarder ces nœuds en correspondance jusqu'à ce que la boucle se termine. Remarque : le résultat n'inclut pas les nœuds elem
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 )
La fonction add ajoute une expression spécifiée à la correspondance actuelle element élément de la formule et renvoyé sous forme d'objet jQuery. add peut recevoir : un sélecteur (chaîne), du contenu HTML (chaîne), un élément DOM (Element) et un objet jQuery. Le traitement est relativement simple, il suffit d'aller au code source
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) ); },
not et filter sont les deux collections de l'opération elle-même, il ne s'agit pas de filtrer les éléments de la collection elle-même qui répondre au sélecteur de conditions de filtrage, en laissant les autres éléments. Le filtre consiste à laisser les éléments qui répondent au sélecteur de conditions de filtre.
La clé est la fonction winnow(elements, qualifier, keep). La fonction de cette fonction est d'effectuer la même fonction de filtrage ou de non-filtrage. Il existe trois types de qualificateurs de condition de filtre : les fonctions, les nœuds DOM et les chaînes. keep : true signifie conserver les éléments qui répondent aux conditions de filtre, false signifie conserver les éléments qui ne répondent pas aux conditions de filtre.
Les commentaires sur le code source de winnow sont les suivants
//执行相同的过滤或者不过滤的功能 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 est utilisé, cliquez ici pour une explication détaillée de grep.
jQuery.filter(expr, elems, not) Cette API de bas niveau est spécialement utilisée pour gérer le cas où la condition de filtre dans jQuery.fn.filter est une chaîne.
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教程