fonction addCombinator(matcher, combinator, base)
1、源码
return combinator.first ?
// Vérification par rapport à l'ancêtre/élément précédent le plus proche
fonction (elem, contexte, xml) {
while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
return matcher(elem, contexte, xml);
>
>
} :
// Vérifier par rapport à tous les éléments ancêtres/précédents
fonction (elem, contexte, xml) {
var data, cache, externalCache, dirkey = dirruns " " doneName;
// Nous ne pouvons pas définir de données arbitraires sur les nœuds XML, donc ils ne le font pas
// bénéficier de la mise en cache du répertoire
si (xml) {
while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
if (matcher(elem, contexte, xml)) {
renvoie vrai ;
>
>
>
} autre {
while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
externalCache = elem[expando] || (elem[expando] = {});
si ((cache = externalCache[dir])
&& cache[0] === répertoire) {
if ((data = cache[1]) === true
|| data === cachedruns) {
renvoyer les données === vrai ;
>
} autre {
cache = externalCache[dir] = [ dirkey ];
cache[1] = matcher(elem, contexte, xml)
|| cachedruns;
if (cache[1] === vrai) {
renvoie vrai ;
>
>
>
>
>
};
>
2、功能
生成关系选择器的执行函数。
3、参数
matcher——是否符合选择器要求。在实际执行过程中,该函数可能是关系选择器前已Il s'agit d'elementMatcher(matchers)。例如:div.map>span,et Sizzle编译遇到>时,会将div.map的编译函数作为第一个参数调用addCombinator函数, 以检查获取的span父节点是否满足div.map这两个条件。
combinateur——关系选择器对应Expr.relative中的值,Expr.relative中各种关系选择器的值如下。使用该参数的first属性来确定返回的是仅检查紧邻对象的函数还是遍历所有Description du produit
base - Ce paramètre, avec combinator.dir, détermine la valeur de la variable checkNonElement. Le code est le suivant. Cette valeur signifie littéralement que la vérification actuelle est un élément non-DOM, c'est-à-dire que lorsque elem.nodeType!=1, si la valeur est vraie, la fonction correspondante sera exécutée, sinon la boucle se terminera.
4. Fonction de retour
4.1 Si le sélecteur de relation est > ou , la fonction suivante est renvoyée :
4.1.1 Fonction
Si le nœud de type d'élément est vérifié (c'est-à-dire checkNonElements==false), obtenez de manière itérative le premier nœud de type d'élément de la relation de position spécifiée par elem (elem.nodeType == 1), exécutez la fonction de correspondance, vérifiez si le nœud répond aux exigences, et renvoie true s'il répond aux exigences, sinon renvoie false
Si tous les types de nœuds sont vérifiés (c'est-à-dire checkNonElements==true), obtenez les nœuds adjacents avec la relation de position spécifiée d'elem, exécutez la fonction de correspondance, vérifiez si le nœud répond aux exigences, retournez true s'il répond aux exigences , sinon renvoie false
Certains se demanderont peut-être : ne dit-on pas qu'il s'agit d'une relation de voisinage étroit ? Alors pourquoi le processus d’acquisition itérative apparaît-il dans le code ? En effet, certains navigateurs considéreront les sauts de ligne entre les textes des nœuds comme TextNode, donc pendant le traitement, ces nœuds doivent être ignorés jusqu'au nœud d'élément suivant.
4.1.2 Paramètres
elem – l’élément de nœud unique à vérifier.
context - le nœud de contexte qui effectue la correspondance complète de la chaîne de sélection, la plupart du temps, il est inutile.
xml——L'objet de recherche actuel est-il un document HTML ou XML ? S'il s'agit de HTML, le paramètre xml est faux.
4.2 Si le sélecteur de relation est ~ ou espace, la fonction suivante sera renvoyée :
// Nous ne pouvons pas définir de données arbitraires sur les nœuds XML, donc ils ne le font pas
// bénéficier de la mise en cache du répertoire
si (xml) {
while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
Si (matcher(elem, contexte, xml)) {
Renvoie vrai ;
>
>
>
} autre {
while ((elem = elem[dir])) {
if (elem.nodeType === 1 || checkNonElements) {
externalCache = elem[expando] || (elem[expando] = {});
Si ((cache = externalCache[dir])
&& cache[0] === répertoire) {
Si ((data = cache[1]) === true
|| data === cachedruns) {
renvoie des données === vrai ;
>
} autre {
cache = externalCache[dir] = [dirkey];
cache[1] = matcher(elem, contexte, xml)
|| exécutions en cache ;
Si (cache[1] === vrai) {
return true ;
>
>
>
>
>
};
4.2.1 Fonction
Si vous vérifiez un document XML, le processus est le même que la fonction de retour dans 4.1. Voir le code entre accolades dans if (XML) { ... } dans le code ci-dessus.
S'il s'agit d'un document HTML, faites correspondre l'élément actuel en fonction du matcher. Si la correspondance est réussie, renvoyez true sinon, renvoyez false.
4.2.2 Paramètres
elem – l’élément de nœud unique à vérifier.
context - le nœud de contexte qui effectue la correspondance complète de la chaîne de sélection, la plupart du temps, il est inutile.
xml——L'objet de recherche actuel est-il un document HTML ou XML ? S'il s'agit de HTML, le paramètre xml est faux.
4.2.3 Description du code
Variables internes
dirkey - la clé utilisée pour mettre en cache les résultats de détection des nœuds. Lors d'une exécution, si un nœud est vérifié, le résultat de la détection (vrai ou faux) sera enregistré dans l'attribut dirkey du nœud (le nom de l'attribut est la valeur de dirkey puis lors de cette exécution, s'il est rencontré à nouveau en atteignant celui-ci). nœud, il n’est pas nécessaire de le détecter à nouveau. La raison pour laquelle la mise en cache est nécessaire est que plusieurs nœuds auront le même nœud parent ou frère. L'utilisation de la mise en cache peut réduire le nombre de détections et améliorer les performances.
dirruns - Chaque fois que le code précompilé organisé par matcherFromGroupMatchers est exécuté, un nombre pseudo-aléatoire sera généré pour distinguer les différents processus d'exécution.
doneName——Chaque fois que la fonction addCombinator est exécutée, la variable done sera incrémentée de 1 pour distinguer les différentes fonctions de correspondance de relation de position générées.
cachedruns - utilisé pour enregistrer à quel élément DOM correspond cette correspondance. Par exemple : div.map>span, il y a 3 éléments qui correspondent au sélecteur de durée, puis lorsque la fonction de correspondance > est exécutée pour chaque élément, les mises en cache sont 0, 1 et 2 dans l'ordre. Selon le code, le rôle des cachedruns peut être directement compris car lors d'un processus d'exécution, lors de l'utilisation d'elementMatchers pour le même élément pour la correspondance, lorsque le même élément est rencontré à nouveau, le résultat sans correspondance peut être obtenu directement à partir de C'est ce qui se passe. Si quelqu'un le rencontre, n'hésitez pas à me le faire savoir, merci !
Explication du code