Rumah > Artikel > hujung hadapan web > Operasi penapisan siri analisis kod sumber Jquery 1.9.1
Tanpa berlengah lagi, mari terus ke topik.
jQuery.fn.find( selector )
find menerima pemilih ungkapan parameter: pemilih (rentetan), elemen DOM (Elemen), objek jQuery. Ia dikendalikan dalam dua situasi:
Yang pertama, jika parameter masuk adalah bukan rentetan, mula-mula cari pemilih melalui pemilih jQuery, dan kemudian tapis item sepadan yang terkandung dalam semasa Objek jQuery Nod elemen.
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; } } }) ); }
Anda boleh melihat bahawa jQuery.contains( self[ i ], this ) ialah kunci dalam keadaan penapis Fungsi ini menggunakan fungsi dalam pemilih Sizzle . Terdapat analisis dalam enjin Sizzle, klik untuk butiran.
Kedua, jika pemilih ialah rentetan, panggil jQuery.find (= Sizzle) untuk memprosesnya terus
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 )
Parameter kedua adalah pilihan. Fungsi ini digunakan untuk memilih elemen pertama yang sepadan dengan ungkapan yang ditentukan, bermula dari elemen padanan semasa, dan mengembalikannya dalam bentuk objek jQuery.
Ungkapan di sini termasuk: pemilih (rentetan), elemen DOM (Elemen) dan objek jQuery.
Langkah pemprosesan dalam kod ialah
1. Mula-mula tanya keputusan mengikut parameter yang diluluskan dan simpan dalam pos.
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? jQuery( selectors, context || this.context ) : 0;
2. Lintas setiap elemen objek jQuery semasa Bermula dari elemen ini, pilih elemen nenek moyang pertama yang sepadan dengan ungkapan yang ditentukan langkah demi langkah.
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 );
Kaedah ibu bapa() dan .closest() adalah serupa kerana kedua-duanya melintasi pokok DOM. Tetapi perbezaannya juga sangat besar: paling dekat mencari yang pertama yang memenuhi syarat dan menamatkannya; ibu bapa mendapati semua set yang memenuhi syarat.
jQuery.fn. ibu bapa/ ibu bapa/ ibu bapaSehingga/ seterusnya/ sebelum/ seterusnyaSemua/ sebelumSemua/ seterusnyaSehingga/ sebelum/ adik beradik/ anak/ kandungan penjelasan terperinci
Kumpulan di atas daripada penapis diproses bersama, kod sumber adalah seperti berikut
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 ); }; });
Dapat dilihat bahawa langkah penapisan ini adalah konsisten. Setiap elemen padanan objek jQuery semasa terlebih dahulu digantikan ke dalam fungsi padanan (fn) yang sepadan melalui fungsi peta untuk mendapatkan hasilnya, dan kemudian penapisan seterusnya dilakukan.
Mari kita lihat penapisan berikutnya dahulu (penapisan benih alternatif telah diperolehi melalui jQuery.map( ini, fn, sehingga ))
Pertama sekali, tidak semua fungsi penapisan mempunyai sehingga Parameter ini hanya diperlukan untuk beberapa penapis yang berakhir dengan Until Penapis lain hanya mempunyai parameter pemilih.
if ( !runtil.test( name ) ) { selector = until; }
Kedua, jika ada pemilih, tapis hasil carian sebelumnya melalui ret pemilih
if ( selector && typeof selector === "string" ) { ret = jQuery.filter( selector, ret ); }
Kemudian, guaranteedeedUnique Terdapat beberapa syarat penapisan (kanak-kanak/kandungan/seterusnya/sebelumnya Apabila bilangan elemen yang dipadankan dengan objek jQuery semasa adalah berbilang, hasil yang diperolehi melalui setiap elemen padanan disimpan dalam set keputusan ret, dan tidak perlu Buang berat. . Pemeriksaan lain perlu dilakukan. Klik untuk melihat penjelasan terperinci kaedah jQuery.unique
ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
Di samping itu, kes khas yang perlu dikendalikan ialah: Jika terdapat berbilang elemen yang dipadankan dengan jQuery semasa objek, gunakan ibu bapa /prevUntil / prevSemua Keputusan ketiga-tiga penapis ini perlu diisih dalam susunan terbalik. Sebab keperluan untuk susunan terbalik: jQuery.unique menggunakan fungsi pengisihan Sizzle .uniqueSort dalam enjin Sizzle Fungsi pengisihan ini menyusun objek dari objek paling atas ke objek paling bawah dalam dokumen.
if ( this.length > 1 && rparentsprev.test( name ) ) { ret = ret.reverse(); }
Akhir sekali, kembalikan hasil yang dibungkus
return this.pushStack( ret );
Struktur rangka kerja tema yang disebutkan di atas, mari kita bincangkan perkara ini Untuk dua fungsi jQuery.dir dan jQuery.sibling yang digunakan dalam fungsi pemadanan penapis kumpulan, pergi terus ke kod sumber
// Cari dir bermula dari nod yang sepadan dengan dir yang ditentukan oleh elem elemen semasa dan simpan nod ini dalam dipadankan dalam sehingga gelung tamat. Nota: Hasilnya tidak termasuk nod 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 )
Fungsi tambah menambah ungkapan tertentu pada padanan semasa elemen elemen formula dan dikembalikan sebagai objek jQuery. tambah boleh menerima: pemilih (rentetan), kandungan HTML (rentetan), elemen DOM (Elemen), dan objek jQuery. Pemprosesan agak mudah, hanya pergi ke kod sumber
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) ); },
bukan dan penapis adalah kedua-dua koleksi operasi itu sendiri, bukan untuk menapis item dalam koleksi itu sendiri yang memenuhi pemilih keadaan penapisan, meninggalkan item lain . Penapis adalah untuk meninggalkan item yang memenuhi pemilih keadaan penapis.
Kuncinya ialah fungsi winnow(elemen, qualifier, keep). Fungsi fungsi ini adalah untuk melaksanakan fungsi penapisan atau bukan penapisan yang sama. Terdapat tiga jenis kelayakan keadaan penapis: fungsi, nod DOM dan rentetan. simpan: benar bermaksud menyimpan item yang memenuhi syarat penapis, palsu bermaksud menyimpan item yang tidak memenuhi syarat penapis.
Komen kod sumber winnow adalah seperti berikut
//执行相同的过滤或者不过滤的功能 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 digunakan, klik di sini untuk penjelasan terperinci tentang grep.
jQuery.filter(expr, elems, not) API peringkat rendah ini digunakan khas untuk mengendalikan kes di mana keadaan penapis dalam jQuery.fn.filter ialah rentetan.
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教程