304 votes

Comment vérifier en Javascript si un élément est l'enfant d'un autre

Comment vérifier si un élément du DOM est l'enfant d'un autre élément du DOM? Existe-t-il des méthodes intégrées pour cela? Par exemple, quelque chose comme:

 if (element1.hasChild(element2)) 
 

ou

 if (element2.hasParent(element1)) 
 

Si non alors des idées comment faire cela? Il doit également être cross browser. Je devrais également mentionner que l'enfant pourrait être imbriqué de nombreux niveaux en dessous du parent.

450voto

Brian Di Palma Points 518

Utilisez Node.contains, il est maintenant standard et disponible dans tous les navigateurs. https://developer.mozilla.org/en-US/docs/Web/API/Node.contains

304voto

Asaph Points 56989

L'utilisation de la propriété parentNode devrait fonctionner. C'est aussi assez sûr d'un point de vue multi-navigateur. Si la relation est connue pour être d'un niveau, vous pouvez le vérifier simplement:

 if (element2.parentNode == element1) { ... }
 

Si l'enfant peut être imbriqué de manière arbitraire au fond du parent, vous pouvez utiliser une fonction semblable à celle-ci pour tester la relation:

 function isDescendant(parent, child) {
     var node = child.parentNode;
     while (node != null) {
         if (node == parent) {
             return true;
         }
         node = node.parentNode;
     }
     return false;
}
 

49voto

GitaarLAB Points 4086

J'ai juste eu à partager "mien".

Bien que conceptuellement le même que Asaph réponse (bénéficiant de la même croix-compatibilité avec les navigateurs, même IE6), il est beaucoup plus petit et est très pratique lorsque la taille est à une prime et/ou lorsqu'il n'est pas nécessaire si souvent.

function childOf(/*child node*/c, /*parent node*/p){ //returns boolean
  while((c=c.parentNode)&&c!==p); 
  return !!c; 
}

..ou en tant que one-liner (64 caractères!):

function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}

et jsfiddle ici.


Utilisation:
childOf(child, parent) retourne un booléen true|false.

Explication:
while évalue aussi longtemps que le tout-condition est évaluée true.
L' && (ET) de l'opérateur renvoie ce booléen (true/false) après l'évaluation de la gauche et de la droite, mais seulement si la gauche était vrai (left-hand && right-hand).

La gauche ( &&) est de: (c=c.parentNode).
Ce sera d'abord attribuer l' parentNode de c de c , puis l'opérateur ET permettra d'évaluer la résultante c comme une valeur booléenne.
Depuis parentNode retours null si il n'y a pas de parent à gauche et null est converti false, le tout en boucle correctement s'arrêter quand il n'y a plus de parents.

Le côté droit ( &&) est de: c!==p.
L' !== opérateur de comparaison est"pas exactement égal à". Donc, si le parent de l'enfant n'est pas le parent (que vous avez spécifié) il évalue true, mais si le parent de l'enfant est le parent ensuite, elle évalue à false.
Donc, si c!==p a la valeur false, alors l' && opérateur retourne false comme le tout-état et la alors la boucle s'arrête. (Remarque il n'est pas nécessaire pour le bien du corps et de clôture, ; point-virgule est nécessaire.)

Ainsi, lorsque la alors la boucle se termine, c est soit un nœud (pas null) quand il a trouvé un parent OU est - null (lorsque la boucle a couru jusqu'à la fin sans trouver un match).

Ainsi, nous avons simplement return (converti en une valeur booléenne, à la place du nœud) avec: return !!c;: ! (NOT opérateur) inverse d'une valeur booléenne (true devient false , et vice-versa).
!c convertit c (nœud ou nulle) à une valeur booléenne avant de pouvoir inverser cette valeur. L'ajout d'un second ! (!!c) convertit ce faux retour de vrai (c'est pourquoi un double - !! est souvent utilisé pour convertir rien boolean').


Extra:
La fonction du corps/de la charge utile est si petit que, selon le cas (comme quand il n'est pas souvent utilisé et apparaît une seule fois dans le code), on peut omettre la fonction (emballage) et il suffit d'utiliser le tout en boucle:

var a=document.getElementById('child'),
    b=document.getElementById('parent'),
    c;

c=a; while((c=c.parentNode)&&c!==b); //c=!!c;

if(!!c){ //`if(c)` if `c=!!c;` was used after while-loop above
    //do stuff
}

au lieu de:

var a=document.getElementById('child'),
    b=document.getElementById('parent'),
    c;

function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}

c=childOf(a, b);    

if(c){ 
    //do stuff
}

22voto

torazaburo Points 6335

Jetez un coup d'œil à Node # compareDocumentPosition .

 function isDescendant(ancestor,descendant){
    return ancestor.compareDocumentPosition(descendant) & 
        Node.DOCUMENT_POSITION_CONTAINS;
}

function isAncestor(descendant,ancestor){
    return descendant.compareDocumentPosition(ancestor) & 
        Node.DOCUMENT_POSITION_CONTAINED_BY;
}
 

Les autres relations incluent DOCUMENT_POSITION_DISCONNECTED , DOCUMENT_POSITION_PRECEDING et DOCUMENT_POSITION_FOLLOWING .

Non pris en charge dans IE <= 8.

3voto

RashFlash Points 389

Je suis tombé sur un formidable morceau de code sur Internet pour vérifier si un élément est un enfant d'un autre élément ou non. Je dois l'utiliser car IE ne prend pas en charge le '.contains' de java-script. espérons que cela aidera aussi les autres gars.

Ci-dessous la fonction: -

 function isChildOf(ChildObject,ContainerObject) 
                { 
                        var retval=false; 
                        var curobj; 
                        if(typeof(ContainerObject)=="string")
                        {
                                ContainerObject=document.getElementById(ContainerObject);
                        }
                        if(typeof(ChildObject)=="string")
                        {
                                ChildObject=document.getElementById(ChildObject);
                        }
                        curobj=ChildObject.parentNode; 
                        while(curobj!=undefined) 
                        { 
                                if(curobj==document.body) 
                                {
                                        break;
                                } 
                                if(curobj.id==ContainerObject.id)
                                {
                                        retval =true;
                                        break;
                                }
                                curobj=curobj.parentNode;//move up the hierarchy 
                        } 
                        return retval; 
                }
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X