日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
詳解jQuery構(gòu)造器的實現(xiàn)

2009-01-13發(fā)布的1.3版

 
 
 
  1. init: function( selector, context ) {  
  2.  // Make sure that a selection was provided  
  3.     selector = selector || document;  
  4.     // 處理節(jié)點參數(shù),直接添加屬性到新實例上  
  5.     if ( selector.nodeType ) {  
  6.         this[0] = selector;  
  7.         this.length = 1;  
  8.         this.context = selector;  
  9.         return this;  
  10.     }  
  11.     // 處理字符串參數(shù)  
  12.     if ( typeof selector === "string" ) {  
  13.         // 判定是否為HTML片斷還是ID  
  14.         var match = quickExpr.exec( selector );  
  15.             if ( match && (match[1] || !context) ) {  
  16.              // 如果是HTML片斷,轉(zhuǎn)換一個由節(jié)點構(gòu)造的數(shù)組  
  17.             if ( match[1] )  
  18.                selector = jQuery.clean( [ match[1] ], context );     
  19.             // 如果是ID,則查找此元素,如果找到放進(jìn)空數(shù)組中  
  20.             else {  
  21.                 var elem = document.getElementById( match[3] );   
  22.                 // Make sure an element was located  
  23.                 if ( elem ){  
  24.                     // 處理 IE and Opera 混淆ID與NAME的bug  
  25.                     if ( elem.id != match[3] )  
  26.                         return jQuery().find( selector );  
  27.                     var ret = jQuery( elem );  
  28.                     ret.context = document;  
  29.                     ret.selector = selector;  
  30.                     return ret;  
  31.                 }  
  32.                 selector = [];  
  33.             }  
  34.         } else 
  35.         //使用Sizzle處理其他CSS表達(dá)式,生成實例并返回  
  36.             return jQuery( context ).find( selector );  
  37.         // 處理函數(shù)參數(shù),直接domReady  
  38.     } else if ( jQuery.isFunction( selector ) )  
  39.         return jQuery( document ).ready( selector );  
  40.      //處理jQuery對象參數(shù),簡單地將其兩個屬性賦給新實例  
  41.     if ( selector.selector && selector.context ) {  
  42.         this.selector = selector.selector;  
  43.         this.context = selector.context;  
  44.     }  
  45.     //將上面得到節(jié)點數(shù)組,用setArray方法把它們變成實例的元素  
  46.     return this.setArray(jQuery.makeArray(selector));  
  47. }, 

2009-02-19發(fā)布的1.32版

 
 
 
  1. init: function( selector, context ) {  
  2.     // Make sure that a selection was provided  
  3.     selector = selector || document;  
  4.     // 處理節(jié)點參數(shù),直接添加屬性到新實例上  
  5.     if ( selector.nodeType ) {  
  6.         this[0] = selector;  
  7.         this.length = 1;  
  8.         this.context = selector;  
  9.         return this;  
  10.     }  
  11.      //處理字符串參數(shù)  
  12.     if ( typeof selector === "string" ) {  
  13.         //判定是否為HTML片斷還是ID  
  14.         var match = quickExpr.exec( selector );  
  15.         if ( match && (match[1] || !context) ) {  
  16.            // 如果是HTML片斷,轉(zhuǎn)換一個由節(jié)點構(gòu)造的數(shù)組  
  17.             if ( match[1] )  
  18.                 selector = jQuery.clean( [ match[1] ], context );  
  19.             else {  
  20.                 var elem = document.getElementById( match[3] );  
  21.                 // 如果是ID,則查找此元素,如果找到放進(jìn)空數(shù)組中  
  22.                 if ( elem && elem.id != match[3] )  
  23.                   return jQuery().find( selector );  
  24.                    //這里對1.3版做了些優(yōu)化,更簡潔  
  25.                 var ret = jQuery( elem || [] );  
  26.                 ret.context = document;  
  27.                 ret.selector = selector;  
  28.                 return ret;  
  29.             }  
  30.         } else 
  31.             //使用Sizzle處理其他CSS表達(dá)式,生成實例并返回  
  32.             return jQuery( context ).find( selector );  
  33.            // 處理函數(shù)參數(shù),進(jìn)行domReady操作  
  34.     } else if ( jQuery.isFunction( selector ) )  
  35.         return jQuery( document ).ready( selector );  
  36.         //處理jQuery對象參數(shù),簡單地將其兩個屬性賦給新實例  
  37.     if ( selector.selector && selector.context ) {  
  38.         this.selector = selector.selector;  
  39.         this.context = selector.context;  
  40.     }  
  41. //這里對1.3版做了些擴(kuò)展,允許傳珍上元素集合(HTMLCollection)與節(jié)點集合(NodeList),  
  42. //元素數(shù)組可能是我們用字符串轉(zhuǎn)換過來的,也可以是用戶直接傳進(jìn)來的  
  43.     return this.setArray(jQuery.isArray( selector ) ? selector : jQuery.makeArray(selector));  
  44. }, 

2010-01-13發(fā)布的1.4版

 
 
 
  1. init: function( selector, context ) {  
  2.     var match, elem, ret, doc;  
  3.     //處理空白字符串,null,undefined參數(shù)(新增),返回一個非常純凈的實例  
  4.     if ( !selector ) {  
  5.         return this;  
  6.     }  
  7.     // 處理節(jié)點參數(shù),直接添加屬性到新實例上  
  8.     if ( selector.nodeType ) {  
  9.         this.context = this[0] = selector;//寫法上優(yōu)化  
  10.         this.length = 1;  
  11.         return this;  
  12.     }  
  13.     //處理字符串參數(shù)  
  14.     if ( typeof selector === "string" ) {  
  15.         //  判定是否為HTML片斷還是ID  
  16.         match = quickExpr.exec( selector );  
  17.         if ( match && (match[1] || !context) ) {  
  18.             //如果是HTML片斷  
  19.             if ( match[1] ) {  
  20.                 //取得文檔對象  
  21.                 doc = (context ? context.ownerDocument || context : document);  
  22.                 // 如果是單個標(biāo)簽,直接使用 document.createElement創(chuàng)建此節(jié)點并放入數(shù)組中  
  23.                 ret = rsingleTag.exec( selector );  
  24.                 if ( ret ) {  
  25.                     //如果后面跟著一個純凈的JS對象,則為此節(jié)點添加相應(yīng)的屬性或樣式  
  26.                     if ( jQuery.isPlainObject( context ) ) {  
  27.                         selector = [ document.createElement( ret[1] ) ];  
  28.                         jQuery.fn.attr.call( selector, context, true );  
  29.                     } else {  
  30.                         selector = [ doc.createElement( ret[1] ) ];  
  31.                     }  
  32.                 } else {  
  33.                     //改由buildFragment來生成節(jié)點集合(NodeList)  
  34.                     ret = buildFragment( [ match[1] ], [ doc ] );  
  35.                     selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;  
  36.                 }  
  37.             } else {  
  38.                 // 如果是ID,則查找此元素,如果找到放進(jìn)空數(shù)組中  
  39.                 elem = document.getElementById( match[2] );  
  40.                 if ( elem ) { 
  41.                     // 處理 IE and Opera 混淆ID與NAME的bug  
  42.                     if ( elem.id !== match[2] ) {  
  43.                         return rootjQuery.find( selector );  
  44.                     }  
  45.                     //這里也做了一些優(yōu)化,原來是很傻地再生成一個jQuery實例  
  46.                     this.length = 1;  
  47.                     this[0] = elem;  
  48.                 }  
  49.                 this.context = document;  
  50.                 this.selector = selector;  
  51.                return this;  
  52.             }    
  53.             // 如果字符是很簡單的標(biāo)簽選擇器,那基本沒有必要走Sizzle路線,直接getElementsByTagName,很好的優(yōu)化  
  54.         } else if ( !context && /^\w+$/.test( selector ) ) {  
  55.             this.selector = selector;  
  56.             this.context = document;  
  57.             selector = document.getElementsByTagName( selector );  
  58.             // 如果第二個參數(shù)不存在或者是jQuery對象,那么用它或rootjQuery調(diào)用find查找目標(biāo)節(jié)點(走Sizzle路線)  
  59.         } else if ( !context || context.jquery ) {  
  60.             return (context || rootjQuery).find( selector );  
  61.             // HANDLE: $(expr, context)  
  62.             // (which is just equivalent to: $(context).find(expr)  
  63.         } else {  
  64.             //如果第二個參數(shù)已指定為某元素節(jié)點,轉(zhuǎn)為jQuery對象,走Sizzle路線  
  65.             return jQuery( context ).find( selector );  
  66.         }  
  67.            // 處理函數(shù)參數(shù),直接domReady  
  68.     } else if ( jQuery.isFunction( selector ) ) {  
  69.         return rootjQuery.ready( selector );  
  70.     }  
  71.     //處理jQuery對象參數(shù),簡單地將其兩個屬性賦給新實例  
  72.     if (selector.selector !== undefined) {  
  73.         this.selector = selector.selector;  
  74.         this.context = selector.context;  
  75.     }  
  76. //這里又做了些許修改,緣于makeArray可以接受第二個參數(shù)(可以是數(shù)組或類數(shù)組,這時相當(dāng)合并操作)  
  77.     return jQuery.isArray( selector ) ?  
  78.         this.setArray( selector ) ://內(nèi)部用push方法,迅速將一個普通對象變成類數(shù)組對象  
  79.         jQuery.makeArray( selector, this );  
  80. }, 

接著是廣受歡迎的2010-02-13發(fā)布的1.42版

 
 
 
  1. init: function( selector, context ) {  
  2.     var match, elem, ret, doc; 
  3.     // 處理空白字符串,null,undefined參數(shù)  
  4.     if ( !selector ) {  
  5.         return this;  
  6.     }  
  7.     // 處理節(jié)點參數(shù)  
  8.     if ( selector.nodeType ) {  
  9.         this.context = this[0] = selector;  
  10.         this.length = 1;  
  11.         return this;  
  12.     }     
  13.     // 處理body參數(shù)(新增)  
  14.     if ( selector === "body" && !context ) {  
  15.         this.context = document;  
  16.         this[0] = document.body;  
  17.         this.selector = "body";  
  18.         this.length = 1;  
  19.         return this;  
  20.     }  
  21.     // 處理字符串參數(shù),分七種情形:  
  22.     //①單個標(biāo)簽,帶對象屬性包           --->   jQuery.merge  
  23.     //②單個標(biāo)簽,不帶對象屬性包         --->   attr + jQuery.merge  
  24.     //③復(fù)雜的HTML片斷                 --->   buildFragment + jQuery.merge  
  25.     //④ID選擇器,與找到的元素的ID不同   --->   getElementById + Sizzle + pushStack  
  26.     //⑤ID選擇器,與找到的元素的ID相同   --->   getElementById + 簡單屬性添加  
  27.     //⑥標(biāo)簽選擇器                     --->   getElementsByTagName + jQuery.merge  
  28.     //⑦其他CSS表達(dá)式                  --->   Sizzle + pushStack  
  29.     if ( typeof selector === "string" ) {  
  30.         match = quickExpr.exec( selector );  
  31.         if ( match && (match[1] || !context) ) {  
  32.             if ( match[1] ) {  
  33.                 doc = (context ? context.ownerDocument || context : document);  
  34.                 ret = rsingleTag.exec( selector );  
  35.                 if ( ret ) {  
  36.                   if ( jQuery.isPlainObject( context ) ) {  
  37.                         selector = [ document.createElement( ret[1] ) ];  
  38.                         jQuery.fn.attr.call( selector, context, true );  
  39.                     } else {  
  40.                         selector = [ doc.createElement( ret[1] ) ];  
  41.                     }  
  42.                 } else {  
  43.                     ret = buildFragment( [ match[1] ], [ doc ] );  
  44.                     selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;  
  45.                 }  
  46.                 return jQuery.merge( this, selector );  
  47.             } else {  
  48.                 elem = document.getElementById( match[2] );  
  49.                 if ( elem ) {  
  50.                     if ( elem.id !== match[2] ) {  
  51.                         return rootjQuery.find( selector );  
  52.                     }  
  53.                     this.length = 1;  
  54.                     this[0] = elem;  
  55.                 }  
  56.                 this.context = document;  
  57.                 this.selector = selector;  
  58.                 return this;  
  59.             }  
  60.         } else if ( !context && /^\w+$/.test( selector ) ) {  
  61.             this.selector = selector;  
  62.             this.context = document;  
  63.             selector = document.getElementsByTagName( selector );  
  64.             return jQuery.merge( this, selector );  
  65.         } else if ( !context || context.jquery ) {  
  66.             return (context || rootjQuery).find( selector );  
  67.         } else {  
  68.            return jQuery( context ).find( selector );  
  69.         }  
  70.         // 處理函數(shù)參數(shù),直接domReady  
  71.     } else if ( jQuery.isFunction( selector ) ) {  
  72.         return rootjQuery.ready( selector );  
  73.     }  
  74.     //處理jQuery對象參數(shù)  
  75.     if (selector.selector !== undefined) {  
  76.         this.selector = selector.selector;  
  77.         this.context = selector.context;  
  78.     }  
  79.     //無論是數(shù)組還是類數(shù)組(如NodeList),統(tǒng)統(tǒng)使用jQuery.makeArray來為實例添加新的元素  
  80.     return jQuery.makeArray( selector, this );  
  81. }, 

另附上makeArray方法與merge方法,merge方法好神奇啊

 
 
 
  1. makeArray: function( array, results ) {  
  2.     var ret = results || [];   
  3.     if ( array != null ) {  
  4.         // The window, strings (and functions) also have 'length'  
  5.         // The extra typeof function check is to prevent crashes  
  6.         // in Safari 2 (See: #3039)  
  7.         if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {  
  8.             push.call( ret, array );  
  9.         } else {  
  10.             jQuery.merge( ret, array );  
  11.         }  
  12.     }  
  13.     return ret;  
  14. },  
  15. merge: function( first, second ) {  
  16.     var i = first.length, j = 0;   
  17.     if ( typeof second.length === "number" ) {  
  18.         for ( var l = second.length; j < l; j++ ) {  
  19.             first[ i++ ] = second[ j ];  
  20.         }  
  21.     } else {  
  22.         while ( second[j] !== undefined ) {  
  23.             first[ i++ ] = second[ j++ ];  
  24.         }  
  25.     }  
  26.     first.length = i;  
  27.     return first;  
  28. }, 

2011-01-23發(fā)布的1.5版,其init方法與1.42的變化不大:只有兩處做了改動:

 
 
 
  1. //1.42  
  2. -  ret = buildFragment( [ match[1] ], [ doc ] );  
  3. -  selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;  
  4. //1.5  
  5. + ret = jQuery.buildFragment( [ match[1] ], [ doc ] );  
  6. + selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;  
  7. //1.42  
  8. - return jQuery( context ).find( selector );  
  9. //1.5  
  10. + return this.constructor( context ).find( selector );//目的就是為了不再生成新實例 

2011-05-02發(fā)布的jquery1.6,變化不大,只是對HTML片斷進(jìn)行了更嚴(yán)密的判定:

 
 
 
  1. // Are we dealing with HTML string or an ID?  
  2.    if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {  
  3.   // Assume that strings that start and end with <> are HTML and skip the regex check  
  4.     match = [ null, selector, null ];  
  5.    } else {  
  6.     match = quickExpr.exec( selector );  
  7.    } 

總體來說,jQuery的構(gòu)造器已經(jīng)做得非常之***,基本上達(dá)到“改無可改”的地步了。但是要保證其高效運作,我們還需要一點選擇器的知識與了解buildFragment方法的運作,因為這兩個實在太常用了,但也是最耗性能的。


網(wǎng)站名稱:詳解jQuery構(gòu)造器的實現(xiàn)
標(biāo)題鏈接:http://www.5511xx.com/article/djhehcp.html