この記事では、jQuery ソース コード解釈の addClass() メソッドをより詳細に分析します。皆さんの参考に共有してください。具体的な分析は次のとおりです。
jQuery.fn.extend({
/*
これは、addClass という名前の関数を備えたプラグイン メソッドであることがわかります。
*/
AddClass: function( value ) {
var クラス、elem、cur、clazz、j、finalValue、
i = 0、
/*
これは、クラスとして追加されるセレクターによって選択された jQuery オブジェクトを表し、len は jQuery オブジェクトの配列の長さです。
*/
len = this.length,
//1 つのオペランドがブール値ではない場合、&& 演算は必ずしもブール値を返すわけではありません。このとき、次の規則に従います:
//1. 最初のオペランドがブール型でない場合は、2 番目のオペランドを返します。
//2. 2 番目のオペランドがブール型でない場合、最初のオペランドの評価結果が true の場合にのみオブジェクトが返されます。
//3. どちらのオペランドもブール型でない場合は、2 番目のオペランドを返します。
//4. オペランドの 1 つが null の場合、
を返します。
//5. オペランドの 1 つが NaN の場合、NaN を返します。
//6. いずれかのオペランドが未定義の場合は、未定義を返します。
//ケース 1: 値が null の場合、ルール 4 に準拠し、null を返します。つまり、値は null になります。
//ケース 2: 値が未定義の場合 (ルール 6 に準拠)、未定義が返されます。つまり、続行値は未定義です。
//ケース 3: 値が NaN の場合、ルール 5 に準拠し、NaN を返します。つまり、値は NaN になります。
//ケース 4: value が数値型の場合、false を返します;
//ケース 5: 値がブール型の場合、false を返します;
//ケース 7: value が Array、Object、Function 型の場合、ルール 2 に準拠しますが、typeof value === 'string' が false であるため、オブジェクトが返され、false が返されます。
//ケース 8: value が文字列型でルール 2 を満たす場合、value を返します。
//したがって、この文は値が文字列型であるかどうかを判断し、文字列値を返して続行することしかできません。他の型は、最終的に false を返すか、暗黙的に false に変換できる型です。
続行 = 値のタイプ === "文字列" && 値;
//上記では文字列型かどうかしか判定できないので、次の文は値がFunction型かどうかを判定します。判定にはjQueryのグローバル関数isFunctionを使用します。これが$.isFunction()です。
if ( jQuery.isFunction( value ) ) {
//値が関数型の場合は、ここに進みます。
//チェーン呼び出し用の jQuery オブジェクトを返します。
//これはセレクターによって選択された jQuery オブジェクトです。
return this.each(function( j ) {
//反復を開始します。ここでは this は jQuery オブジェクトではなく、現在の反復の DOM オブジェクトであるため、jQuery(this) でラップされて jQuery オブジェクトになり、jQuery メソッドを使用できるようになります。 j は各走査のインデックスを表します。値を返す値関数を渡してクラス名を設定します。 value 関数は、毎回現在の DOM を実行オブジェクトとして呼び出し、現在の DOM インデックス値とクラス名を渡します。value 関数によって返された値は、jQuery(this).addClass (戻り値) によって再度呼び出されます。 () メソッドが再度呼び出されます。文字列が返された場合は、別の if 分岐が実行されます。返された関数がまだ関数である場合は、返された関数の呼び出しを続けます。
jQuery( this ).addClass( value.call( this, j, this.className ) );
});
}
//前に取得したプロシージャは文字列です。ここでは、空でない文字列が暗黙的に true に変換されるかどうかを判断します。空の文字列は暗黙的に false に変換されるため、if ステートメント ブロックは実行されなくなり、プログラムは最後の return this にジャンプし、jQuery オブジェクトが返されて実行が完了します。
if (続行) {
//空ではない文字列に進み、if ステートメント ブロックの実行を開始します。値は「show bd1」であると仮定します。
//rnotwhite は正規表現 (/S /g) であり、空白以外の文字を 1 回以上グローバルに一致させることを意味します。
//(value || "") は非常に単純な "show bd1" を返します。
//"show bd1".match((/S /g)) || [] は ["show", "bd1"] を返します。 match の意味がわからない場合は、調べてください。
クラス = ( 値 || "" ).match( rnotwhite ) ||
//ここで、classes は ['show', 'bd1'] クラス名を追加する配列です。
// 以下のトラバースを開始し、各 DOM オブジェクトのクラスを追加します。
for ( ; i
//これは jQuery オブジェクト、elem は現在の DOM オブジェクトです。
elem = this[i];
/*
=== 演算子は && 演算子よりも優先されます。まず、DOM ノード タイプが要素ノードであるかどうかを判断します。
rclass は正規表現/[trnf]/g;
括弧内の三項演算子は、現在の DOM ノードにクラスが既に存在するかどうかを示します。存在する場合、クラス内に存在する可能性のあるタブ文字、改行文字、復帰文字などがスペース " " を含む文字列に置き換えられます。 、現在のクラスの前後にスペースを追加します。現在の DOM ノードにクラスがない場合は、スペース " " を含む文字列も指定されます。最後に
になります
cur = elem.nodeType === 1 && "show bd1"、これは非常によく知られています。はい、最初の 6 つのルールに従って評価されます。
elem のノード タイプが 1 であると仮定し、次に cur = true && " "、最後に cur = "show bd1" とします。
elem のノード タイプが 1 でない場合は、cur = false && " "、そして最後に cur = false になります。
*/
Cur = elem.nodeType === 1 && ( elem.className ?
( " " elem.className " " ).replace( rclass, " " ):" ");
//今度は cur = "show bd1" として、実行する if ステートメント ブロックに入ります。
If ( cur ) {
j = 0;
/*
クラスは ["show bd1"]
です
現在の DOM 要素が既に持っているクラスに、追加するクラスが既に存在するかどうかをループして確認します。
そうでない場合は、このクラスを追加します。
*/
While ((Clazz = クラス [J]) {
If ( cur.indexOf( " " clazz " " )
cur = clazz "";
}
}
/*
最後に、$.trim() を使用して、クラス「show bd1」の両端のスペース文字を削除します。
現在の DOM 要素のクラスが結合されたクラスと同じかどうかを確認します。同じクラスのレンダリングの不必要な重複を避けてください。
*/
finalValue = jQuery.trim( cur );
If ( elem.className !== FinalValue ) {
に
}
}
}
}
// 今後のチェーン呼び出しのためにこの jQuery オブジェクトを返します。
これを返します;
}
});