著者: nuysoft/Gao Yun QQ: 47214707 メール: nuysoft@gmail.com
声明: この記事はオリジナルの記事です。転載する必要がある場合は、出典を明記し、元のリンクを保持してください。
Sizzle ソース コードを分析する前に、セレクターの動作原理を整理しましょう。
最初に、後で読むときに曖昧さがないよう、セレクターで使用されるいくつかの名詞を明確にします。 >セレクター式: "div > p"
ブロック式: "div" "p"
列セレクター式: "div, p"
ブロック スプリッター: Sizzle の通常のチャンカー、選択用 式は分割されています
ファインダー: ブロック式を検索し、見つかった DOM 要素の配列を候補セットと呼びます。
フィルター: ブロック式と候補セットをフィルターします。
関係フィルターは、ブロック式と候補セットの間の関係をフィルターします。ブロック式には合計 4 つの関係があります: " " 直接の兄弟関係、"" 先祖関係、および "~" の後のすべての兄弟関係。ファインダー、フィルターによってフィルター処理されます
マップ セット: 候補セットのコピー、マップ セットをフィルターするためのフィルターおよびリレーショナル フィルター
ワークフロー:
1 ブロック スプリッターを使用します。セレクター式を左から右に分割します
カンマ「,」で分割された並列セレクター式が見つかった場合は、最初のカンマの前の選択部分のみに分割します コンバーター式 1、残りの部分を記録します
2. Sizzle.find で最後のブロック式を検索し、結果を候補セットに入れ、ブロック式内の一致する文字列部分を削除します
ファインダー Sizzle.find は、正規セット Expr から対応する正規表現を取得します。 match し、ブロック式と一致します。一致が成功した場合、検索関数セット Expr.find から対応する検索関数を取得して実行します。
検索順序は Expr.order で定義されます。順序は次のとおりです。 NAME TAG。CLASS を検索する場合、ブラウザは getElementsByClassName をサポートする必要があります。
Expr.match は ID の正規一致表現を設定します。 CLASS NAME ATTR TAG CHILD POS PSEUDO
3. 最後のブロック式が空でない場合(文字列)、フィルター Sizzle.filter はセットをフィルター処理します
フィルター Sizzle.filter は単一のブロック式および候補セット内の要素に対してのみ機能します 候補セット内の要素が残りの条件を満たすことを確認して機能しますブロック式
フィルタ Sizzle.filter のフィルタリング処理中に、条件を満たさないものは false に設定され、条件を満たすものはフィルタリング時に変更されません
正規表現から対応する正規表現を取得しますExpr.leftMatch を設定し、ブロック式と一致します。一致が成功した場合は、Expr.filter から対応するフィルター関数を取得して実行します。
Expr.leftMatch は、Expr.match と同じ数の正規表現を定義します。 式: ID クラス名ATTR TAG CHILD POS PSEUDO
フィルター関数セット Expr.filter は PSEUDO CHILD ID TAG CLASS ATTR POS
Filter のフィルター関数を定義します Sizzle.filter はフィルター処理の前にプレフィルター Expr を呼び出します .preFilter はフィルター処理に必要なパラメーターを修正します, ただし、CLASSは例外です
CLASSが事前フィルタリングされた場合、クラスに一致する要素を直接候補セットとして返すように最適化され、フィルタリング範囲と候補セット範囲が狭められます
上記で取得した候補セットセットをコピーします以降のフィルタリング操作は checkSet
に対して実行されます。最後のブロック式の検索とフィルタリングはここで終了し、候補セット セットとマッピング セット checkSet
4. マッピング セット checkSet の残りのブロック式を右から左にフィルターし、前のブロック式との関係に基づいて関係フィルター セット Expr.relative から対応する関数を取得します。
関係フィルタ Expr.relative のフィルタリング処理において、条件を満たさないものは false に設定され、条件を満たしているものは親要素、祖先要素、兄弟要素の関係に設定されます
4 つのタイプがあります: " " 直接の兄弟関係; " 父と息子の関係 "" 先祖関係; "~" の後のすべての兄弟関係。式がタグ TAG である場合、タグ タイプ nodeName を直接比較して等しいかどうかを確認します。
タグ TAG ではない場合、フィルター Sizzle.filter が呼び出されてフィルターされます。フィルタリング プロセスについては、ステップ 3 を参照してください。
> 右からすべてのブロック式がフィルターされるまで左をフィルターします
5. フィルターされたマッピング セット checkSet に従って、マッピング セット checkSet
が null の場合、最終結果セットを選択します。 、 false、フィルタリングされます
要素 (nodeType===1) ではない場合、フィルタリングされます
コンテキストがドキュメントではなく要素であり、要素の子要素ではない場合、フィルタリングされますfiltered
6. 並列式がある場合は 1 ~ 5 を繰り返し、最終的な結果セットをマージ、ソート、重複排除します
セレクター式が 1 つだけで並列セレクター式がない場合はソートなしは必須です
以下の処理はSizzleに属しませんが、SizzleのjQuery拡張に属します
7。複数のコンテキストがある場合は、コンテキストごとに1〜6を繰り返します
複数のコンテキスト例: $(' div').find('div > p')、$('div') は複数の div を見つけることができます
実際、ステップ 7 は jQuery セレクターへの入り口です ステップ 7 から 1 を呼び出します。 ~6、空の jQuery オブジェクトを結果セットとして渡すとき
デフォルトでは、ドキュメントはコンテキストです: (context || rootjQuery).find( selector )
8. 結果をマージして削除します。複数のコンテキストから見つかったセットを繰り返し、結果セットを返します
完了!