jQueryセレクタのソースコード解釈(5):tokenize_jqueryの解析処理
次の分析は、jQuery-1.10.2.js バージョンに基づいています。
以下では $("div:not(.class:contain('span')):eq(3)") を例として、解析を完了するためにトークン化コードと preFilter コードがどのように調整されるかを説明します。 tokenize メソッドと preFilter クラスのコードの各行の詳細な説明を知りたい場合は、次の 2 つの記事を参照してください。
http://www.jb51.net/article/63155.htm
http://www.jb51.net/article/63163.htm
以下は tokenize メソッドのソース コードです。わかりやすくするために、キャッシュ、カンマ マッチング、リレーショナル文字マッチングに関連するコードをすべて削除し、現在の例に関連するコア コードのみを残しています。削除されたコードは非常に単純です。必要に応じて、上記の記事を参照してください。
また、コードは説明文の上に書かれています。
関数 tokenize(selector, parseOnly) {
var matched、match、tokens、type、soFar、groups、preFilters;
これまで = セレクター;
グループ = [];
preFilters = Expr.preFilter;
その間 (これまで) {
if (!matched) {
groups.push(トークン = []);
}
一致 = false;
for (Expr.filter に入力) {
If ((match = matchExpr[type].exec(soFar))
&& (!preFilters[タイプ] || (match = preFilters[タイプ]
(一致)))) {
一致 = match.shift();
tokens.push({
値: 一致、
タイプ: タイプ、
一致: match
});
SoFar = soFar.slice(matched.length);
}
}
if (!matched) {
休憩;
}
}
return parseOnly ? soFar.length : soFar.error(selector) :
tokenCache(セレクター、グループ).slice(0);
}
まず、jQuery の実行中に select メソッドによって初めて tokenize が呼び出され、「div:not(.class:contain('span')):eq(3)」がセレクター パラメーターとしてメソッドに渡されます。
これまで = セレクター;
これまで = "div:not(.class:contain('span')):eq(3)"
初めて while ループに入ると、matched には値が割り当てられていないため、if 内の次のステートメント本体が実行され、トークン変数が初期化され、トークンがグループ配列にプッシュされます。
groups.push(トークン = []);
最初の for ループ: Expr.filter から最初の要素「TAG」を取得し、それを type 変数に割り当て、ループ本体のコードを実行します。
&& (!preFilters[タイプ] || (match = preFilters[タイプ]
(一致)))) {
一致 =["div", "div"]
例の最初のセレクターは div で、matchExpr["TAG"] の正規表現に一致しますが、preFilters["TAG"] が存在しないため、if 内のステートメント本体が実行されます。
tokens.push({
値: 一致、
タイプ: タイプ、
一致: match
}
新しいオブジェクト { value: "div"、type: "TAG"、matches: ["div"] } を作成し、そのオブジェクトをトークン配列にプッシュします。
SoFar = soFar.slice(matched.length);
soFar 変数は div を削除します。このとき、soFar=":not(.class:contain('span')):eq(3)"
2 番目の for ループ: Expr.filter から 2 番目の要素「CLASS」を取得し、それを type 変数に割り当て、ループ本体のコードを実行します。
If ((match = matchExpr[type].exec(soFar))
&& (!preFilters[タイプ] || (match = preFilters[タイプ]
(一致)))) {
現在の soFar=":not(.class:contain('span')):eq(3)" は CLASS 型の正規表現と一致しないため、このループは終了します。
3 番目の for ループ: Expr.filter から 3 番目の要素「ATTR」を取得し、それを type 変数に割り当て、ループ本体のコードを実行します。
同様に、現在残っているセレクターは属性セレクターではないため、このサイクルは終了します。
4 番目の for ループ: Expr.filter から 4 番目の要素「CHILD」を取得し、それを type 変数に割り当て、ループ本体のコードを実行します。
同様に、現在残っているセレクターは CHILD セレクターではないため、このサイクルは終了します。
5 番目の for ループ: Expr.filter から 5 番目の要素「PSEUDO」を取得し、それを type 変数に割り当て、ループ本体のコードを実行します。
If ((match = matchExpr[type].exec(soFar))
&& (!preFilters[タイプ] || (match = preFilters[タイプ]
(一致)))) {
match = matchExpr[type].exec(soFar) の実行結果は次のとおりです。
[":not(.class:contain('span')):eq(3)", "not", ".class:contain('span')):eq(3", 未定義, 未定義, 未定義, 未定義、未定義、未定義、未定義、未定義]
preFilters["PSEUDO"] が存在するため、次のコードが実行されます:
match = preFilters[type](match)
preFilters["PSEUDO"] コードは次のとおりです:
"PSEUDO" : function(match) {
var extra、引用符なし = !match[5] && match[2];
if (matchExpr["CHILD"].test(match[0])) {
null を返す;
}
if (match[3] && match[4] !== 未定義) {
一致[2] = 一致[4];
} else if (引用符なし
&& rpseudo.test(引用符なし)
&& (excess = tokenize(unquoted, true))
&& (過剰 = unquoted.indexOf(")", unquoted.length
- 過剰)
- unquoted.length)) {
match[0] = match[0].slice(0, 過剰);
match[2] = unquoted.slice(0, 過剰);
}
return match.slice(0, 3);
}
渡された一致パラメータは次と同じです:
[":not(.class:contain('span')):eq(3)", "not", ".class:contain('span')):eq(3", 未定義, 未定義, 未定義, 未定義、未定義
引用符なし = !match[5] && match[2]
引用なし = ".class:contain('span')):eq(3"
if (matchExpr["CHILD"].test(match[0])) {
null を返します。 }
一致[2] = 一致[4]
; }
&& rpseudo.test(unquoted)
&& (excess = tokenize(unquoted, true))
&& (超過 = unquoted.indexOf(")", unquoted.length - 超過) - unquoted.length)
の後にfor文を入力します。
現在残っているセレクターはTAGセレクターではないため、このサイクルは終了します。
match = matchExpr[type].exec(soFar) の実行結果は次のとおりです。
preFilters["CLASS"]が存在しないため、if内の文本体が実行されます。
match の最初の要素クラスを削除し、その要素を matched="class", match = ["class"]
に代入します。
コードをコピーします
}
新しいオブジェクト { value: "class"、type: "CLASS"、matches: ["class"] } を作成し、そのオブジェクトをトークン配列にプッシュします。
soFar = soFar.slice(matched.length);
3 番目の for ループ: Expr.filter から 3 番目の要素「ATTR」を取得し、それを type 変数に割り当て、ループ本体のコードを実行します。
同様に、現在残っているセレクターは属性セレクターではないため、このサイクルは終了します。
同様に、現在残っているセレクターは CHILD セレクターではないため、このサイクルは終了します。
&& (!preFilters[type] || (match = preFilters[type]
(一致)))) {
[":contain('span')", "contain", "'span'", "'", "span", 未定義, 未定義, 未定義, 未定義, 未定義, 未定義]
var 過剰、引用符なし = !match[5] && match[2];
If (matchExpr["CHILD"].test(match[0])) {
null を返す; }
If (一致[3] && 一致[4] !== 未定義) {
一致[2] = 一致[4];
} else if (引用符なし
&& (excess = tokenize(unquoted, true)) && (excess = unquoted.indexOf(")", unquoted.length
- 過剰)
- unquoted.length)) {
match[0] = match[0].slice(0, 過剰)
match[2] = unquoted.slice(0, 過剰)
}
match.slice(0, 3) を返します。 }
受信一致パラメータは次と同じです:
[":contain('span')", "contain", "'span'", "'", "span", 未定義, 未定義, 未定義, 未定義, 未定義, 未定義]
コードをコピーします
コードは次のとおりです:
「:contain('span')」は matchExpr["CHILD"] 正規表現と一致しないため、内部ステートメント本体は実行されません。
if (一致[3] && 一致[4] !== 未定義) {
一致[2] = 一致[4];
}
match[3] = "'" かつ match[4] ="span" なので、内部の if 文本体が実行され、match[2] に "span" が代入されます
match.slice(0, 3) を返します。
このとき、tokenizeメソッドのforループに戻って実行を継続します。このときの各変数の値は以下の通りです。
一致 = [":contain('span')", "contain", "span"]
これまで = ":contain('span')):eq(3"
一致配列から「:contain('span')」を削除し、一致した変数に割り当てます
一致 : 一致
}
soFar変数は「:contain('span')」を削除し、その後、forループが終了して再度whileループが実行されるまで、soFar="):eq(3)"となります。有効なセレクターがないため、while ループを終了します。
コードをコピー
このとき parseOnly = true なので、この時点の soFar の長さ 6 が返され、preFilters["PSEUDO"] のコードが実行され続けます
余分な変数に 6 を代入し、コード
コードをコピー
コードをコピー
match[0] = ":not(.class:contain('span'))"
match[2] = ".class:contain('span')"
コードをコピー
コードは次のとおりです:
一致する最初の 3 つの要素のコピーを返します。
トークン化関数に戻り、match = [":not(.class:contain('span'))", "not", ".class:contain('span')"]
一致 = match.shift();
match = ["not", ".class:contain('span')"]
値: 一致、
タイプ: タイプ、
一致 : 一致
}
group[0][1] = {値: ":not(.class:contain('span'))"、タイプ: "PSEUDO"、一致: ["not"、".class:contain('スパン')"] }
グループ[0][2] = {値: ":eq(3)"、タイプ: "PSEUDO"、一致: ["eq", "3"] }
parseOnly = 未定義のため、tokenCache(selector, groups).slice(0) が実行され、グループがキャッシュにプッシュされ、そのコピーが返されます。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









jQuery 参照方法の詳細説明: クイック スタート ガイド jQuery は、Web サイト開発で広く使用されている人気のある JavaScript ライブラリであり、JavaScript プログラミングを簡素化し、開発者に豊富な機能を提供します。この記事では、jQuery の参照方法を詳しく紹介し、読者がすぐに使い始めるのに役立つ具体的なコード例を示します。 jQuery の導入 まず、HTML ファイルに jQuery ライブラリを導入する必要があります。 CDN リンクを通じて導入することも、ダウンロードすることもできます

jQueryでPUTリクエストメソッドを使用するにはどうすればよいですか? jQuery で PUT リクエストを送信する方法は、他のタイプのリクエストを送信する方法と似ていますが、いくつかの詳細とパラメータ設定に注意する必要があります。 PUT リクエストは通常、データベース内のデータの更新やサーバー上のファイルの更新など、リソースを更新するために使用されます。以下は、jQuery の PUT リクエスト メソッドを使用した具体的なコード例です。まず、jQuery ライブラリ ファイルが含まれていることを確認してから、$.ajax({u

jQueryで要素の高さ属性を削除するにはどうすればよいですか?フロントエンド開発では、要素の高さ属性を操作する必要が生じることがよくあります。要素の高さを動的に変更する必要がある場合や、要素の高さ属性を削除する必要がある場合があります。この記事では、jQuery を使用して要素の高さ属性を削除する方法と、具体的なコード例を紹介します。 jQuery を使用して高さ属性を操作する前に、まず CSS の高さ属性を理解する必要があります。 height 属性は要素の高さを設定するために使用されます

タイトル: jQuery ヒント: ページ上のすべての a タグのテキストをすばやく変更する Web 開発では、ページ上の要素を変更したり操作したりする必要がよくあります。 jQuery を使用する場合、ページ内のすべての a タグのテキスト コンテンツを一度に変更する必要がある場合があります。これにより、時間と労力を節約できます。以下では、jQuery を使用してページ上のすべての a タグのテキストをすばやく変更する方法と、具体的なコード例を紹介します。まず、jQuery ライブラリ ファイルを導入し、次のコードがページに導入されていることを確認する必要があります: <

タイトル: jQuery を使用して、すべての a タグのテキスト コンテンツを変更します。 jQuery は、DOM 操作を処理するために広く使用されている人気のある JavaScript ライブラリです。 Web 開発では、ページ上のリンク タグ (タグ) のテキスト コンテンツを変更する必要が生じることがよくあります。この記事では、この目標を達成するために jQuery を使用する方法を説明し、具体的なコード例を示します。まず、jQuery ライブラリをページに導入する必要があります。 HTML ファイルに次のコードを追加します。

jQuery は、Web ページでの DOM 操作やイベント処理を処理するために広く使用されている人気のある JavaScript ライブラリです。 jQueryではeq()メソッドを利用して指定したインデックス位置の要素を選択しますが、具体的な使い方と応用シーンは以下の通りです。 jQuery では、 eq() メソッドは、指定されたインデックス位置にある要素を選択します。インデックス位置は 0 からカウントされます。つまり、最初の要素のインデックスは 0、2 番目の要素のインデックスは 1 などとなります。 eq() メソッドの構文は次のとおりです。 $("s

jQuery 要素に特定の属性があるかどうかを確認するにはどうすればよいですか? jQuery を使用して DOM 要素を操作する場合、要素に特定の属性があるかどうかを判断する必要がある状況がよく発生します。この場合、jQuery が提供するメソッドを使用してこの関数を簡単に実装できます。以下では、jQuery 要素が特定の属性を持つかどうかを判断するために一般的に使用される 2 つの方法を紹介し、具体的なコード例を添付します。方法 1: attr() メソッドと typeof 演算子 // を使用して、要素に特定の属性があるかどうかを判断します

jQuery は、Web 開発で広く使用されている人気の JavaScript ライブラリです。 Web 開発中は、JavaScript を使用してテーブルに新しい行を動的に追加することが必要になることがよくあります。この記事では、jQuery を使用してテーブルに新しい行を追加する方法を紹介し、具体的なコード例を示します。まず、jQuery ライブラリを HTML ページに導入する必要があります。 jQuery ライブラリは、次のコードを通じてタグに導入できます。
