ホームページ  >  記事  >  ウェブフロントエンド  >  jQueryセレクターのソースコード解釈(8):addCombinator function_jquery

jQueryセレクターのソースコード解釈(8):addCombinator function_jquery

WBOY
WBOYオリジナル
2016-05-16 16:06:541023ブラウズ

関数 addCombinator(マッチャー、コンビネーター、ベース)

1、ソースコード

复制代 代码如下:

function addCombinator(マッチャー、コンビネーター、ベース) {
 var dir = combinator.dir、checkNonElements = Base
   && dir === "parentNode"、doneName = 完了 ;

combinator.first を返します ?
 // 最も近い祖先/前の要素と照合します
 関数(要素、コンテキスト、xml) {
  while ((elem = elem[dir])) {
   if (elem.nodeType === 1 || checkNonElements) {
    return matcher(elem, context, xml);
   }
  }
 } :

// すべての祖先/先行要素と照合します
 関数(要素、コンテキスト、xml) {
  var data、cache、outerCache、dirkey = dirruns " " DoneName;

// XML ノードには任意のデータを設定できないため、
  // dir キャッシュの恩恵を受ける
  if (xml) {
   while ((elem = elem[dir])) {
    if (elem.nodeType === 1 || checkNonElements) {
     if (matcher(elem, context, xml)) {
      true を返します;
     }
    }
   }
  } else {
   while ((elem = elem[dir])) {
    if (elem.nodeType === 1 || checkNonElements) {
     externalCache = elem[expando] || (elem[expando] = {});
     if ((キャッシュ = externalCache[dir])
       && キャッシュ[0] === dirkey) {
      if ((データ = キャッシュ[1]) === true
        ||データ === キャッシュラン) {
       戻りデータ === true;
      }
     } else {
      キャッシュ = externalCache[dir] = [ dirkey ];
      キャッシュ[1] = matcher(elem, context, xml)
        ||キャッシュされた実行;
      if (キャッシュ[1] === true) {
       true を返します;
      }
     }
    }
   }
  }
 };
}

2、機能

システム選択器の実行関数を生成します。

3、パラメータ

matcher - 位置関連で継続的に実行されるフィルタ・セレクタ関数の数グループ。この関数は、位置関連によって取得されるポイントが、実際の実行中にシステム・セレクタの要求に適合するかどうかを照合するために使用されます。例: div.map>span、Sizzle での評価に到達したとき、div.map の関数を最初のパラメータとして addCombinator 関数として使用し、取得したスパンの父ポイントがあるかどうかを検査します。この 2 つの条件を div.map に満たします。

コンビネータ - Expr.relative の関連システム セレクションの値。このパラメータの最初のプロパティを使用して、返されるオブジェクトがすべて検査される関数であることを確認します。
次のコード: elem = elem[dir] によって、dir が combinator.dir に等しい位置関係のポイントを取得します。

复制代码代码如下:

Expr.relative : {
 「>」 : {
  ディレクトリ: "親ノード",
  最初: true
 }、
 " " : {
  ディレクトリ: "親ノード"
 }、
 " " : {
  ディレクトリ: "previousSibling",
  最初: true
 }、
 "~" : {
  ディレクトリ: "previousSibling"
 }
}

base - このパラメータは combinator.dir とともに、変数 checkNonElement の値を決定します。コードは次のとおりです。この値は文字通り、現在のチェックが非 DOM 要素であることを意味すると理解されます。つまり、elem.nodeType!=1 の場合、値が true の場合、一致する関数が実行され、それ以外の場合はループが終了します。

4. 戻り関数

4.1 関係セレクターが > または の場合、次の関数が返されます。

コードをコピー コードは次のとおりです:
関数(要素、コンテキスト、xml) {
while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
return matcher(elem, context, xml);
}
}
}

4.1.1 機能

要素型ノードがチェックされている場合(つまり、checkNonElements==false)、要素指定の位置関係(elem.nodeType == 1)の最初の要素型ノードを反復的に取得し、マッチング関数を実行し、ノードが要件を満たしているかどうかを確認します。要件を満たしている場合は true を返し、そうでない場合は
を返します。

すべてのタイプのノードがチェックされている場合 (つまり、checkNonElements==true)、elem の指定された位置関係を持つ隣接ノードを取得し、マッチング関数を実行し、ノードが要件を満たしているかどうかを確認し、要件を満たしている場合は true を返しますそれ以外の場合は false を返します。 「密接な隣人関係って言われてるんじゃないの?」と疑問に思う人もいるかもしれません。では、なぜ反復取得のプロセスがコードに現れるのでしょうか?これは、一部のブラウザではノード テキスト間の改行を TextNode と見なすため、処理中にこれらのノードを次の要素ノードまでスキップする必要があるためです。

4.1.2 パラメータ
elem – チェックされる単一のノード要素。

context - セレクター文字列全体のマッチングを実行するコンテキスト ノード。ほとんどの場合、役に立ちません。

xml——現在の検索オブジェクトは HTML ドキュメントですか?それとも XML ドキュメントですか? HTML の場合、xml パラメータは false です。

4.2 リレーションシップセレクターが ~ またはスペースの場合、次の関数が返されます:


//すべての祖先/先行要素と照合します
関数(要素、コンテキスト、xml) {
var data、cache、outerCache、dirkey = dirruns " " DoneName;

// XML ノードには任意のデータを設定できないため、 // dir キャッシュの恩恵を受ける

if (xml) {
while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
If (matcher(elem, context, xml)) {
true を返します;
}
}
}
} else {
while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
externalCache = elem[expando] || (elem[expando] = {});
If ((キャッシュ = externalCache[dir])
&& キャッシュ[0] === dirkey) {
If ((data = キャッシュ[1]) === true
|| データ === キャッシュ実行) {
データを返す === true;
}
} else {
キャッシュ = externalCache[dir] = [dirkey];
キャッシュ[1] = matcher(elem, context, xml)
|| キャッシュされた実行;
If (cache[1] === true) {
true を返します;
}
}
}
}
}
};

4.2.1 機能

XML ドキュメントをチェックしている場合、プロセスは 4.1 の return 関数と同じです。上記のコードの if (XML) { ... } の中の中括弧内のコードを参照してください。

HTML ドキュメントの場合は、マッチャーに従って現在の要素と一致し、一致した場合は true を返し、それ以外の場合は false を返します。

4.2.2 パラメータ
elem – チェックされる単一のノード要素。

context - セレクター文字列全体のマッチングを実行するコンテキスト ノード。ほとんどの場合、役に立ちません。

xml——現在の検索オブジェクトは HTML ドキュメントですか?それとも XML ドキュメントですか? HTML の場合、xml パラメータは false です。

4.2.3 コードの説明

内部変数

dirkey - ノード検出結果をキャッシュするために使用されるキー。実行中にノードがチェックされると、検出結果 (true または false) がノードの dirkey 属性に記録されます (属性名は dirkey の値です)。この実行中に再び検出された場合は、これに到達します。ノードを再度検出する必要はありません。キャッシュが必要な理由は、複数のノードに同じ親ノードまたは兄弟ノードがあるため、キャッシュを使用すると検出数が減り、パフォーマンスが向上するためです。

dirruns - matcherFromGroupMatchers によって編成されたプリコンパイル済みコードが実行されるたびに、異なる実行プロセスを区別するために疑似乱数が生成されます。
DoneName - addCombinator 関数が実行されるたびに、生成されたさまざまな位置関係マッチング関数を区別するために、done 変数が 1 ずつ増加します。

cachedruns - この一致がどの DOM 要素であるかを記録するために使用されます。たとえば、div.map>span の場合、span セレクターに一致する要素が 3 つあり、各要素に対して > 一致関数が実行されると、cachedrun は順番に 0、1、2 になります。コードによれば、cachedruns の役割は、実行プロセス中に、一致するために同じ要素に対して elementMatchers を使用するときに、同じ要素に再び遭遇したときに、一致しない結果を直接取得できることが起こると直接理解できます。誰かがそれに遭遇したら、私に知らせてください、ありがとう!

コードの説明

コードをコピーします コードは次のとおりです:

while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
// elemノードのexpando属性が存在しない場合は、空のオブジェクトを与えると同時にouterCache
に渡す。 // elemノードのexpando属性が存在する場合、その値をouterCache
に代入する externalCache = elem[expando] || (elem[expando] = {});
/*
* outCache[dir] に値があり、その最初の要素が現在の dirkey と等しい場合、
* これは、現在位置セレクターがこの実行中にノードを検出し、if 内のステートメントを実行し、結果をキャッシュから直接取得したことを意味します
* outCache[dir] が存在しない場合、または最初の要素が現在の dirkey と等しくない場合、
* * これは、現在位置セレクターがこの実行中にノードを検出できず、else でステートメントを実行し、ノードと照合して結果をキャッシュに入れることを意味します
*/
if ((キャッシュ = externalCache[dir])
&& キャッシュ[0] === dirkey) {
// キャッシュ内の検出結果が true または cachedruns の値と等しい場合、検出結果 (false または true) が返されます。
// それ以外の場合は、ループを継続して、一致する
の位置関係に一致する前のノードを取得します。 if ((データ = キャッシュ[1]) === true
|| データ === キャッシュ実行) {
戻りデータ === true;
}
} else {
//配列[dirkey]をouterCache[dir]とcache
に代入する キャッシュ = externalCache[dir] = [ dirkey ];
// 一致が成功した場合は、cache[1] に true を割り当て、そうでない場合は、cachedruns の値をキャッシュ[1] に割り当てます
キャッシュ[1] = matcher(elem, context, xml)
|| キャッシュされた実行;
// マッチング結果が true の場合は true を返し、そうでない場合はループを継続して、マッチング
の位置関係に一致する前のノードを取得します。 if (キャッシュ[1] === true) {
true を返します;
}
}
}
}
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。