明らかに、このステップを実現するための実装は非常に複雑です。この実装は、jQuery の実際のコンストラクターである init メソッドです。バージョンアップとともに機能も強化され、どんどん長くなってきています。
バージョン 1.3 は 2009 年 1 月 13 日にリリースされました
init: function( selector, context ) {
var match, elem, ret, doc;
// 空の文字列、null、未定義のパラメータ (新しく追加された) を処理し、非常に純粋なインスタンスを返します。 of
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 ); >// Pure JS オブジェクトが後に続く場合は、対応する属性またはスタイルをこのノードに追加します
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ]; >jQuery.fn.attr.call(セレクター, コンテキスト, true );
} else {
selector = [ doc.createElement( ret[1] ) ];
/ /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 と Opera における ID と NAME の混同のバグに対処する
if ( elem.id !== match[2] ] ) {
return rootjQuery.find( selector );
}
//ここでいくつかの最適化も行われていますが、別の jQuery インスタンスを生成するのは愚かであることがわかりました。 1;
this[0] = elem;
this.context = document;
return this;この文字は非常に単純なラベル セレクターです。基本的に Sizzle ルートに進む必要はなく、getElementsByTagName を直接取得します。非常に優れた最適化
} else if ( !context && /^w $/.test( selector ) ) {
this.selector = selector;
this.context = document;
selector = document.getElementsByTagName( selector );
// 2 番目のパラメーターが存在しない場合、または jQuery オブジェクトの場合は、それを使用します。 find を呼び出してターゲット ノードを見つけます (Sizzle ルートを選択します)
} else if ( !context || context.jquery ) {
return (context || rootjQuery).find( selector ); / HANDLE: $(expr, context)
// (これは $(context).find(expr)
} と同等です else {
// 2 番目のパラメータが指定されている場合要素ノードを jQuery オブジェクトに変換し、Sizzle ルートを実行します。
return jQuery( context );
}
// 関数パラメータを直接処理します domReady
} else if ( jQuery .isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
// jQuery オブジェクトのパラメータを処理し、その 2 つのプロパティを新しいインスタンスに割り当てます
if (selector.selector !== 未定義) {
this.selector = selector.selector;
this .context = selector.context;
}
//makeArray が 2 番目のパラメータを受け入れることができるため、ここでいくつかの変更が加えられています。パラメータ (配列または配列のようなもので、マージ操作と同等)
return jQuery.isArray( selector ) ?
this.setArray( selector ) ://push メソッドを内部的に使用して、通常のオブジェクトを配列のようなオブジェクトに変換
jQuery.makeArray( selector, this );
} , <🎜> >コードは次のとおりです:
init: function( selector, context ) {
var match, elem, ret, doc;
// 空の文字列、null、未定義のパラメータを処理します
if ( !selector ) {
return this;
}
// ノードパラメータを処理します
if ( selector.nodeType ) {
this.context = this[0] = selector;
return this;
}
// 本体パラメータの処理 (new)
if ( selector === "body" && !context ) {
this.context = document; this[0] = document.body;
this.selector = "body";
return this;
}
// に分割された文字列パラメータ7 つの状況:
//①単一ラベル、オブジェクト属性パッケージあり---> jQuery.merge
//②単一ラベル、オブジェクト属性パッケージなし---> jQuery.merge
//③複合HTML フラグメント ---> buildFragment jQuery.merge
//④見つかった要素の ID とは異なる ID セレクター ---> getElementById Sizzle PushStack
//⑤ ID 選択デバイス見つかった要素の ID ---> getElementById 単純な属性の追加
//⑥ タグセレクター ---> getElementsByTagName jQuery.merge
///⑦ その他の CSS 式 ---> >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 ); selector = [ doc.createElement( ret[1] ) ];
}
} else {
ret = buildFragment( [ match[1] ],
selector = (ret) .cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
}
return jQuery.merge(this, selector );
elem = document.getElementById ( match[2] );
if ( elem ) {
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector ); this.length = 1;
this[0] = elem;
this.selector = セレクター;
>} else if ( !context && /^w $/.test( selector ) ) {
this.selector = selector;
this.context = document;
selector = document.
return jQuery.merge( this, selector );
} else if ( !context || context.jquery ) {
return (context || rootjQuery).find( selector ); {
return jQuery( context ).find( selector );
}
// 関数パラメータを直接処理します domReady
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery. ready( selector );
}
//jQuery オブジェクトのパラメーターを処理します
if (selector.selector !== unknown) {
this.selector = selector.selector; selector.context;
}
// 配列であっても、配列のようなもの (NodeList など) であっても、jQuery.makeArray を使用してインスタンスに新しい要素を追加します
return jQuery.makeArray( selector, this );
makeArray メソッドと merge メソッドが付属しています。
コードをコピーします。
コードは次のとおりです。
makeArray: function( array, results) {
var ret = results ||
if ( array ! = null ) {
// ウィンドウ、文字列 (および関数) にも「長さ」があります
// 追加の typeof 関数チェックは、Safari 2 でのクラッシュを防ぐためのものです
// (参照: # 3039)
if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
if ( typeof Second.length === "number" ) {
for ( var l = Second .length ; j < l j ) {
first[i] = Second[j];
} else {
while ( Second[j] !== 未定義) 🎜> first[ i ] = Second[ j ];
}
}
first.length = i;
},
2011 -01 -23 にリリースされたバージョン 1.5 では、init メソッドが 1.42 からほとんど変更されていません。変更されたのは 2 つだけです:
コードをコピー
コードは次のとおりです:
//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 ] ); .cacheable ? jQuery .clone(ret.fragment) : ret.fragment).childNodes;
//1.42
- return jQuery( context ).find( selector ); this.constructor( context ).find( selector );//新しいインスタンスを生成することが目的ではありません
2011 年 5 月 2 日にリリースされた Jquery 1.6 は、HTML フラグメントの判定が厳しくなったことを除いて、あまり変わっていません:
// 扱うのは HTML 文字列ですか? それとも ID ですか?
if ( selector.charAt(0) === "<" && セレクター。 charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// <> で始まる文字列は HTML であると仮定し、正規表現チェックをスキップします。 🎜>match = [ null, selector, null ];
} else {
match = QuickExpr.exec( selector );
}
一般的には、jQuery の構造この楽器は非常に完成度が高く、基本的には「何も変えられない」というところまで来ています。ただし、効率的な操作を確保するには、セレクターに関するある程度の知識と buildFragment メソッドの操作の理解も必要です。これら 2 つはあまりにも一般的に使用されますが、最もパフォーマンスを消費するためです。
声明:この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。