您好,登錄后才能下訂單哦!
這篇文章給大家介紹jQuery中怎么實現一個構造器,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
2009-01-13發布的1.3版
init: function( selector, context ) { // Make sure that a selection was provided selector = selector || document; // 處理節點參數,直接添加屬性到新實例上 if ( selector.nodeType ) { this[0] = selector; this.length = 1; this.context = selector; return this; } // 處理字符串參數 if ( typeof selector === "string" ) { // 判定是否為HTML片斷還是ID var match = quickExpr.exec( selector ); if ( match && (match[1] || !context) ) { // 如果是HTML片斷,轉換一個由節點構造的數組 if ( match[1] ) selector = jQuery.clean( [ match[1] ], context ); // 如果是ID,則查找此元素,如果找到放進空數組中 else { var elem = document.getElementById( match[3] ); // Make sure an element was located if ( elem ){ // 處理 IE and Opera 混淆ID與NAME的bug if ( elem.id != match[3] ) return jQuery().find( selector ); var ret = jQuery( elem ); ret.context = document; ret.selector = selector; return ret; } selector = []; } } else //使用Sizzle處理其他CSS表達式,生成實例并返回 return jQuery( context ).find( selector ); // 處理函數參數,直接domReady } else if ( jQuery.isFunction( selector ) ) return jQuery( document ).ready( selector ); //處理jQuery對象參數,簡單地將其兩個屬性賦給新實例 if ( selector.selector && selector.context ) { this.selector = selector.selector; this.context = selector.context; } //將上面得到節點數組,用setArray方法把它們變成實例的元素 return this.setArray(jQuery.makeArray(selector)); },
2009-02-19發布的1.32版
init: function( selector, context ) { // Make sure that a selection was provided selector = selector || document; // 處理節點參數,直接添加屬性到新實例上 if ( selector.nodeType ) { this[0] = selector; this.length = 1; this.context = selector; return this; } //處理字符串參數 if ( typeof selector === "string" ) { //判定是否為HTML片斷還是ID var match = quickExpr.exec( selector ); if ( match && (match[1] || !context) ) { // 如果是HTML片斷,轉換一個由節點構造的數組 if ( match[1] ) selector = jQuery.clean( [ match[1] ], context ); else { var elem = document.getElementById( match[3] ); // 如果是ID,則查找此元素,如果找到放進空數組中 if ( elem && elem.id != match[3] ) return jQuery().find( selector ); //這里對1.3版做了些優化,更簡潔 var ret = jQuery( elem || [] ); ret.context = document; ret.selector = selector; return ret; } } else //使用Sizzle處理其他CSS表達式,生成實例并返回 return jQuery( context ).find( selector ); // 處理函數參數,進行domReady操作 } else if ( jQuery.isFunction( selector ) ) return jQuery( document ).ready( selector ); //處理jQuery對象參數,簡單地將其兩個屬性賦給新實例 if ( selector.selector && selector.context ) { this.selector = selector.selector; this.context = selector.context; } //這里對1.3版做了些擴展,允許傳珍上元素集合(HTMLCollection)與節點集合(NodeList), //元素數組可能是我們用字符串轉換過來的,也可以是用戶直接傳進來的 return this.setArray(jQuery.isArray( selector ) ? selector : jQuery.makeArray(selector)); },
2010-01-13發布的1.4版
init: function( selector, context ) { var match, elem, ret, doc; //處理空白字符串,null,undefined參數(新增),返回一個非常純凈的實例 if ( !selector ) { return this; } // 處理節點參數,直接添加屬性到新實例上 if ( selector.nodeType ) { this.context = this[0] = selector;//寫法上優化 this.length = 1; return this; } //處理字符串參數 if ( typeof selector === "string" ) { // 判定是否為HTML片斷還是ID match = quickExpr.exec( selector ); if ( match && (match[1] || !context) ) { //如果是HTML片斷 if ( match[1] ) { //取得文檔對象 doc = (context ? context.ownerDocument || context : document); // 如果是單個標簽,直接使用 document.createElement創建此節點并放入數組中 ret = rsingleTag.exec( selector ); if ( ret ) { //如果后面跟著一個純凈的JS對象,則為此節點添加相應的屬性或樣式 if ( jQuery.isPlainObject( context ) ) { selector = [ document.createElement( ret[1] ) ]; jQuery.fn.attr.call( selector, context, true ); } else { selector = [ doc.createElement( ret[1] ) ]; } } else { //改由buildFragment來生成節點集合(NodeList) ret = buildFragment( [ match[1] ], [ doc ] ); selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; } } else { // 如果是ID,則查找此元素,如果找到放進空數組中 elem = document.getElementById( match[2] ); if ( elem ) { // 處理 IE and Opera 混淆ID與NAME的bug if ( elem.id !== match[2] ) { return rootjQuery.find( selector ); } //這里也做了一些優化,原來是很傻地再生成一個jQuery實例 this.length = 1; this[0] = elem; } this.context = document; this.selector = selector; return this; } // 如果字符是很簡單的標簽選擇器,那基本沒有必要走Sizzle路線,直接getElementsByTagName,很好的優化 } else if ( !context && /^\w+$/.test( selector ) ) { this.selector = selector; this.context = document; selector = document.getElementsByTagName( selector ); // 如果第二個參數不存在或者是jQuery對象,那么用它或rootjQuery調用find查找目標節點(走Sizzle路線) } else if ( !context || context.jquery ) { return (context || rootjQuery).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { //如果第二個參數已指定為某元素節點,轉為jQuery對象,走Sizzle路線 return jQuery( context ).find( selector ); } // 處理函數參數,直接domReady } else if ( jQuery.isFunction( selector ) ) { return rootjQuery.ready( selector ); } //處理jQuery對象參數,簡單地將其兩個屬性賦給新實例 if (selector.selector !== undefined) { this.selector = selector.selector; this.context = selector.context; } //這里又做了些許修改,緣于makeArray可以接受第二個參數(可以是數組或類數組,這時相當合并操作) return jQuery.isArray( selector ) ? this.setArray( selector ) ://內部用push方法,迅速將一個普通對象變成類數組對象 jQuery.makeArray( selector, this ); },
接著是廣受歡迎的2010-02-13發布的1.42版
init: function( selector, context ) { var match, elem, ret, doc; // 處理空白字符串,null,undefined參數 if ( !selector ) { return this; } // 處理節點參數 if ( selector.nodeType ) { this.context = this[0] = selector; this.length = 1; return this; } // 處理body參數(新增) if ( selector === "body" && !context ) { this.context = document; this[0] = document.body; this.selector = "body"; this.length = 1; return this; } // 處理字符串參數,分七種情形: //①單個標簽,帶對象屬性包 ---> jQuery.merge //②單個標簽,不帶對象屬性包 ---> attr + jQuery.merge //③復雜的HTML片斷 ---> buildFragment + jQuery.merge //④ID選擇器,與找到的元素的ID不同 ---> getElementById + Sizzle + pushStack //⑤ID選擇器,與找到的元素的ID相同 ---> getElementById + 簡單屬性添加 //⑥標簽選擇器 ---> getElementsByTagName + jQuery.merge //⑦其他CSS表達式 ---> Sizzle + pushStack if ( typeof selector === "string" ) { match = quickExpr.exec( selector ); if ( match && (match[1] || !context) ) { if ( match[1] ) { doc = (context ? context.ownerDocument || context : document); ret = rsingleTag.exec( selector ); if ( ret ) { if ( jQuery.isPlainObject( context ) ) { selector = [ document.createElement( ret[1] ) ]; jQuery.fn.attr.call( selector, context, true ); } else { selector = [ doc.createElement( ret[1] ) ]; } } else { ret = buildFragment( [ match[1] ], [ doc ] ); selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; } return jQuery.merge( this, selector ); } else { elem = document.getElementById( match[2] ); if ( elem ) { if ( elem.id !== match[2] ) { return rootjQuery.find( selector ); } this.length = 1; this[0] = elem; } this.context = document; this.selector = selector; return this; } } else if ( !context && /^\w+$/.test( selector ) ) { this.selector = selector; this.context = document; selector = document.getElementsByTagName( selector ); return jQuery.merge( this, selector ); } else if ( !context || context.jquery ) { return (context || rootjQuery).find( selector ); } else { return jQuery( context ).find( selector ); } // 處理函數參數,直接domReady } else if ( jQuery.isFunction( selector ) ) { return rootjQuery.ready( selector ); } //處理jQuery對象參數 if (selector.selector !== undefined) { this.selector = selector.selector; this.context = selector.context; } //無論是數組還是類數組(如NodeList),統統使用jQuery.makeArray來為實例添加新的元素 return jQuery.makeArray( selector, this ); },
另附上makeArray方法與merge方法,merge方法好神奇啊
makeArray: function( array, results ) { var ret = results || []; if ( array != null ) { // The window, strings (and functions) also have 'length' // The extra typeof function check is to prevent crashes // in Safari 2 (See: #3039) if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) { push.call( ret, array ); } else { jQuery.merge( ret, array ); } } return ret; }, merge: function( first, second ) { var i = first.length, j = 0; if ( typeof second.length === "number" ) { for ( var l = second.length; j < l; j++ ) { first[ i++ ] = second[ j ]; } } else { while ( second[j] !== undefined ) { first[ i++ ] = second[ j++ ]; } } first.length = i; return first; },
2011-01-23發布的1.5版,其init方法與1.42的變化不大:只有兩處做了改動:
//1.42 - ret = buildFragment( [ match[1] ], [ doc ] ); - selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; //1.5 + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; //1.42 - return jQuery( context ).find( selector ); //1.5 + return this.constructor( context ).find( selector );//目的就是為了不再生成新實例
2011-05-02發布的jquery1.6,變化不大,只是對HTML片斷進行了更嚴密的判定:
// Are we dealing with HTML string or an ID? if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; } else { match = quickExpr.exec( selector ); }
關于jQuery中怎么實現一個構造器就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。