[原創] jQuery源碼分析-11 DOM遍曆-Traversing-DOM遍曆方法

來源:互聯網
上載者:User

作者:nuysoft/高雲 QQ:47214707 Email:nuysoft@gmail.com
聲明:本文為原創文章,如需轉載,請註明來源並保留原文連結。

jQuery源碼分析系列(持續更新)

 

1. 屬性childNodes vs 屬性children

childNodes Retrieves a collection of HTML Elements and TextNode objects that are direct descendants of the specified object.
標準,包含HTML元素、文本
children Retrieves a collection of DHTML Objects that are direct descendants of the object.
非標準,只包含HTML元素

 

2. 方法children vs 方法contents

jQuery.fn.children( elem ) 只包含Element
jQuery.fn.contents( elem ) 包含Element、Text、Comment

 

3. 完整源碼分析(亮點在排序、去重部分)

jQuery.each({parent: function( elem ) { // 父元素var parent = elem.parentNode;return parent && parent.nodeType !== 11 ? parent : null; // DocumentFragment 11, DocumentType 10},parents: function( elem ) { // 祖先元素return jQuery.dir( elem, "parentNode" ); // 檢索所有父元素,直至document},parentsUntil: function( elem, i, until ) { // return jQuery.dir( elem, "parentNode", until );},next: function( elem ) { // 下一個兄弟元素return jQuery.nth( elem, 2, "nextSibling" ); // 從1開始計數,當前是第1個,為什麼要再搞一套不一致的索引方法呢?},prev: function( elem ) { // 上一個兄長元素return jQuery.nth( elem, 2, "previousSibling" );},nextAll: function( elem ) { // 所有的兄弟元素return jQuery.dir( elem, "nextSibling" );},prevAll: function( elem ) { // 所有的兄長元素return jQuery.dir( elem, "previousSibling" );},nextUntil: function( elem, i, until ) { // 所有的兄弟元素,但是不包括untilreturn jQuery.dir( elem, "nextSibling", until );},prevUntil: function( elem, i, until ) { // 所有的兄長元素,但是不包括untilreturn jQuery.dir( elem, "previousSibling", until );},siblings: function( elem ) { // 所有兄長、兄弟元素,不包括當前元素return jQuery.sibling( elem.parentNode.firstChild, elem ); // 父元素的第一個子項目的所有兄弟元素,排除當前元素elem// 取子項目childNodes然後過濾elem,效率更高},children: function( elem ) { // 所有的子節點,只包含Elementreturn jQuery.sibling( elem.firstChild ); // 第一個子項目的所有兄弟元素// 為什麼不直接取子項目呢?childNodes不是效率更高嗎?},contents: function( elem ) { // 所有的子節點,包含Element、Text、Commentreturn jQuery.nodeName( elem, "iframe" ) ? elem.contentDocument || elem.contentWindow.document : // 如果是iframe,則取documentjQuery.makeArray( elem.childNodes ); // 將childNodes轉換數組,childNodes是偽數組,轉換後遍曆數組時可以避免對childNodes進行檢查,提高效能}}, function( name, fn ) {jQuery.fn[ name ] = function( until, selector ) {var ret = jQuery.map( this, fn, until ), // 將this中的元素,用fn處理,最後返回真正的數組,until用於過濾// The variable 'args' was introduced in// https://github.com/jquery/jquery/commit/52a0238// to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.// http://code.google.com/p/v8/issues/detail?id=1050args = slice.call(arguments); // 將arguments複製並轉為數組if ( !runtil.test( name ) ) { // 不以Until結尾selector = until; // 不需要參數until,只有一個參數selector,util只到這裡為止}if ( selector && typeof selector === "string" ) {ret = jQuery.filter( selector, ret ); // 對ret數組用selector進行過濾,只留下匹配的元素// jQuery.filter會調用jQuery.find.matches > Sizzle.matches > Sizzle,Sizzle尋找、過濾的結果已經經過排序、去重}/** * 排序、去重 * 首先要知道this是經過排序、且無重複 * 如果長度大於1,才需要判斷是否需要去重 * 如果name是 children contents next prev 之一,則不需要排序去重,因為這四個方法不會產生無序和重複的結果,為什麼呢? * 因為this中的元素是有序、去重的,所以的它子節點、兄弟、兄長,也都是有序、無重複的 * 但是parent parents parentsUntil nextAll prevAll nextUntil prevUntil siblings卻有可能產生重複、無序的元素 *  * 可見這裡進行了最佳化,不可否則這種編碼習慣很精緻很贊,但是: * 即使不需要排序、去重的情況,也必然要經過這些漫長的判斷,就是一種浪費 * 這種多功能導致的複雜性和無謂的效能消耗,在jQuery中隨處可見 * 雖然沒有做詳盡的效能測試,其實也沒必要,但稍微給我有點“機關算盡太聰明,枉費了卿卿性命”的感覺 * 從剛開始讀源碼時的驚豔和崇拜,漸漸的能分辨其中的精髓與作者的權衡拿捏,jQuery的偉大不可否認, * 但是我們寫代碼的時候,要借鑒參考,也要思考取捨 *  * 上邊的感觸僅供參考,我還處於能讀懂和能分析jQuery源碼的階段,不到自創一套類庫的境界, * 也許水平提高了jQuery不能滿足我的時候,再回頭看,興許是另一重感悟了。 */ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; // 去重// rparentsprev = /^(?:parents|prevUntil|prevAll)/// 因為前邊返回的結果是按照元素在文檔中的位置順序返回的,遇到rparentsprev則需要再反過來,方便使用if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {ret = ret.reverse(); // 倒序}return this.pushStack( ret, name, args.join(",") ); // 構造jQuery對象};})

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.