Heim  >  Artikel  >  Web-Frontend  >  Interpretation des Quellcodes des jQuery-Selektors (8): addCombinator function_jquery

Interpretation des Quellcodes des jQuery-Selektors (8): addCombinator function_jquery

WBOY
WBOYOriginal
2016-05-16 16:06:541018Durchsuche

Funktion addCombinator(matcher, combinator, base)

1、源码

复制代码 代码如下:

Funktion addCombinator(matcher, combinator, base) {
 var dir = combinator.dir, checkNonElements = base
   && dir === "parentNode", doneName = done ;

 return combinator.first ?
 // Vergleich mit dem nächsten Vorfahren/vorhergehenden Element prüfen
 function(elem, context, xml) {
  while ((elem = elem[dir])) {
   if (elem.nodeType === 1 || checkNonElements) {
    return matcher(elem, context, xml);
   }
  }
 } :

 // Vergleich aller Vorgänger-/Vorgängerelemente
 function(elem, context, xml) {
  var data, zwischenspeicher, äußererCache, dirkey = dirruns " " doneName;

  // Wir können keine beliebigen Daten auf XML-Knoten festlegen, also tun sie das auch nicht
  // vom Dir-Caching profitieren
  if (xml) {
   while ((elem = elem[dir])) {
    if (elem.nodeType === 1 || checkNonElements) {
     if (matcher(elem, context, xml)) {
      return true;
     }
    }
   }
  } sonst {
   while ((elem = elem[dir])) {
    if (elem.nodeType === 1 || checkNonElements) {
     äußererCache = elem[expando] || (elem[expando] = {});
     if ((cache = äußererCache[dir])
       && Cache[0] === dirkey) {
      if ((data = Cache[1]) === true
        || data === Cachedruns) {
       Rückgabedaten === true;
      }
     } sonst {
      Cache = OuterCache[dir] = [ dirkey ];
      Cache[1] = Matcher(Elem, Kontext, XML)
        || zwischengespeicherte Runs;
      if (cache[1] === true) {
       return true;
      }
     }
    }
   }
  }
 };
}

2、功能

生成关系选择器的执行函数.

3、参数

Matcher——点是否符合选择器要求.在实际执行过程中,该函数可能是关系选择器前已Verwenden Sie elementMatcher(matchers).以检查获取的span父节点是否满足div.map这两个条件.

Kombinator——关系选择器对应Expr.relative中的值, Expr.relative中各种关的值如下.使用该参数的first属性来确定返回的是仅检查紧邻对象的函数还是遍历所有可能对象的函数。将通过如下代码:elem = elem[dir],获取指定位置关系的节点,其中dir等于combinator.dir。

复制代码 代码如下:

Ausdruck relativ: {
 ">" : {
  dir: „parentNode“,
  Erstens: wahr
 },
 " " : {
  dir: „parentNode“
 },
 " " : {
  dir: „ previousSibling“,
  Erstens: wahr
 },
 „~“ : {
  dir: „ previousSibling“
 }
}

base – Dieser Parameter bestimmt zusammen mit combinator.dir den Wert der Variablen checkNonElement. Der Code lautet wie folgt. Dieser Wert bedeutet wörtlich, dass es sich bei der aktuellen Prüfung um ein Nicht-DOM-Element handelt. Wenn also elem.nodeType! = 1 gilt und der Wert wahr ist, wird die entsprechende Funktion ausgeführt, andernfalls wird die Schleife beendet.

4. Return-Funktion

4.1 Wenn der Beziehungsselektor > ist, wird die folgende Funktion zurückgegeben:

Code kopieren Der Code lautet wie folgt:

function(elem, context, xml) {
while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
Return matcher(elem, context, xml);
}
}
}

4.1.1 Funktion
Wenn der Elementtypknoten überprüft wird (d. h. checkNonElements==false), erhalten Sie iterativ den ersten Elementtypknoten der von elem angegebenen Positionsbeziehung (elem.nodeType == 1), führen Sie die Matching-Funktion aus und prüfen Sie, ob der Knoten die Anforderungen erfüllt. und geben Sie „true“ zurück, wenn es die Anforderungen erfüllt, andernfalls geben Sie „false“ zurück

Wenn alle Knotentypen überprüft werden (d. h. checkNonElements==true), rufen Sie die benachbarten Knoten mit der angegebenen Positionsbeziehung von elem ab, führen Sie die Matching-Funktion aus, prüfen Sie, ob der Knoten die Anforderungen erfüllt, und geben Sie true zurück, wenn er die Anforderungen erfüllt , andernfalls false zurückgeben; Manche Leute fragen sich vielleicht, heißt es nicht, dass es sich um eine enge Nachbarschaftsbeziehung handelt? Warum erscheint der Prozess der iterativen Erfassung im Code? Dies liegt daran, dass einige Browser die Zeilenumbrüche zwischen Knotentexten als TextNode betrachten. Daher müssen diese Knoten während der Verarbeitung bis zum nächsten Elementknoten übersprungen werden.

4.1.2 Parameter
elem – das einzelne Knotenelement, das überprüft werden soll.

Kontext – der Kontextknoten, der den gesamten Selektor-String-Abgleich durchführt, meistens ist er nutzlos.

xml – Ist das aktuelle Suchobjekt ein HTML- oder XML-Dokument? Wenn es HTML ist, ist der XML-Parameter falsch.

4.2 Wenn der Beziehungsselektor ~ oder ein Leerzeichen ist, wird die folgende Funktion zurückgegeben:


//Überprüfe alle Vorfahren/vorhergehenden Elemente
function(elem, context, xml) {
var data, zwischenspeicher, äußererCache, dirkey = dirruns " " doneName;

// Wir können keine beliebigen Daten auf XML-Knoten festlegen, also tun sie das auch nicht // vom Dir-Caching profitieren

if (xml) {
while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
If (matcher(elem, context, xml)) {
Gibt true zurück;
}
}
}
} sonst {
while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
äußererCache = elem[expando] ||. (elem[expando] = {});
If ((cache = äußererCache[dir])
&& Cache[0] === dirkey) {
If ((data = Cache[1]) === true
||. data === zwischengespeicherte Runs) {
        Rückgabedaten === true;
}
} sonst {
Cache = OuterCache[Dir] = [Dirkey];
Cache[1] = Matcher(Elem, Kontext, XML)
||.cachedruns;
If (cache[1] === true) {
        return true;
}
}
}
}
}
};

4.2.1 Funktion

Wenn Sie ein XML-Dokument prüfen, ist der Vorgang derselbe wie bei der Rückgabefunktion in 4.1. Sehen Sie sich den Code in den geschweiften Klammern in if (XML) { ... } im obigen Code an.

Wenn es sich um ein HTML-Dokument handelt, wird das aktuelle Element entsprechend dem Matcher abgeglichen. Wenn der Abgleich erfolgreich ist, wird „true“ zurückgegeben.

4.2.2 Parameter
elem – das einzelne Knotenelement, das überprüft werden soll.

Kontext – der Kontextknoten, der den gesamten Selektor-String-Abgleich durchführt, meistens ist er nutzlos.

xml – Ist das aktuelle Suchobjekt ein HTML- oder XML-Dokument? Wenn es HTML ist, ist der XML-Parameter falsch.

4.2.3 Codebeschreibung

Interne Variablen

dirkey – der Schlüssel, der zum Zwischenspeichern der Knotenerkennungsergebnisse verwendet wird. Wenn während einer Ausführung ein Knoten überprüft wird, wird das Erkennungsergebnis (wahr oder falsch) im dirkey-Attribut des Knotens aufgezeichnet (der Attributname ist der Wert von dirkey). Wenn es dann während dieser Ausführung erneut angetroffen wird, wird es erreicht Knoten, es besteht keine Notwendigkeit, ihn erneut zu erkennen. Der Grund, warum Caching erforderlich ist, liegt darin, dass mehrere Knoten denselben übergeordneten Knoten oder Geschwisterknoten haben. Durch die Verwendung von Caching kann die Anzahl der Erkennungen verringert und die Leistung verbessert werden.

dirruns – Jedes Mal, wenn der von matcherFromGroupMatchers organisierte vorkompilierte Code ausgeführt wird, wird eine Pseudozufallszahl generiert, um verschiedene Ausführungsprozesse zu unterscheiden.
doneName – Jedes Mal, wenn die Funktion addCombinator ausgeführt wird, wird die Variable done um 1 erhöht, um die verschiedenen generierten Positionsbeziehungs-Matching-Funktionen zu unterscheiden.

cachedruns – wird verwendet, um aufzuzeichnen, um welches DOM-Element es sich bei dieser Übereinstimmung handelt. Beispiel: div.map>span, es gibt 3 Elemente, die mit dem Span-Selektor übereinstimmen. Wenn dann die Matching-Funktion für jedes Element ausgeführt wird, sind die zwischengespeicherten Läufe der Reihe nach 0, 1 und 2. Gemäß dem Code kann die Rolle von Cachedruns direkt so verstanden werden, dass während eines Ausführungsprozesses, wenn elementMatchers für dasselbe Element zum Abgleichen verwendet wird und beim erneuten Auftreffen auf dasselbe Element das nicht übereinstimmende Ergebnis direkt von Folgendes abgerufen werden kann. Wenn jemand darauf stößt, lassen Sie es mich bitte wissen, danke!

Code-Erklärung

Code kopieren Der Code lautet wie folgt:

while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
// Wenn das Expando-Attribut des Elem-Knotens nicht vorhanden ist, geben Sie ihm ein leeres Objekt und geben Sie es gleichzeitig an OuterCache
weiter. // Wenn das Expando-Attribut des Elem-Knotens vorhanden ist, weisen Sie seinen Wert OuterCache
zu äußererCache = elem[expando] ||. (elem[expando] = {});
/*
* Wenn outCache[dir] einen Wert hat und sein erstes Element dem aktuellen Verzeichnis entspricht,
* Dies bedeutet, dass der aktuelle Positionsselektor den Knoten während dieser Ausführung erkannt, die Anweisung im if ausgeführt und das Ergebnis direkt aus dem Cache
erhalten hat * Wenn outCache[dir] nicht existiert oder das erste Element nicht dem aktuellen Verzeichnis entspricht,
* * Dies bedeutet, dass der aktuelle Positionsselektor den Knoten während dieser Ausführung nicht erkannt hat, die Anweisung in else ausführt, mit dem Knoten übereinstimmt und das Ergebnis in den Cache legt
*/
if ((cache = äußererCache[dir])
&& Cache[0] === dirkey) {
// Wenn das Erkennungsergebnis im Cache gleich „true“ oder dem Wert von „cachedruns“ ist, wird das Erkennungsergebnis zurückgegeben (entweder „false“ oder „true“),
// Andernfalls fahren Sie mit der Schleife fort, um den vorherigen Knoten zu erhalten, der mit der Positionsbeziehung für den Abgleich
übereinstimmt if ((data = Cache[1]) === true
||. data === zwischengespeicherte Runs) {
Rückgabedaten === true;
}
} sonst {
// Weisen Sie das Array [dirkey] OuterCache[dir] und Cache
zu Cache = OuterCache[dir] = [ dirkey ];
// Wenn die Übereinstimmung erfolgreich ist, weisen Sie Cache[1] „true“ zu, andernfalls weisen Sie Cache[1]
den Wert von „cachedruns“ zu Cache[1] = Matcher(Elem, Kontext, XML)
||.cachedruns;
// Wenn das Übereinstimmungsergebnis wahr ist, geben Sie true zurück, andernfalls fahren Sie mit der Schleife fort, um den vorherigen Knoten zu erhalten, der mit der Positionsbeziehung für den Abgleich
übereinstimmt if (cache[1] === true) {
Gibt true zurück;
}
}
}
}
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn