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.hasDescendant(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.
L'utilisation de la propriété parentNode
devrait fonctionner. C'est également assez sûr d'un point de vue multi-navigateur. Si la relation est connue pour être d'un niveau, vous pouvez la vérifier simplement:
if (element2.parentNode == element1) { ... }
Si l'enfant peut être imbriqué de manière arbitraire au plus profond 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;
}
Vous devez utiliser Node.contains
, car il est maintenant standard et disponible dans tous les navigateurs.
https://developer.mozilla.org/en-US/docs/Web/API/Node.contains
Je devais juste partager le "mien".
Bien que conceptuellement identique à réponse d'Asaph (bénéficiant de la même compatibilité entre navigateurs, même IE6), il s'agit d'un lot plus petit et qui s'avère pratique lorsque la taille est réduite. et/ou quand on n'en a pas besoin si souvent.
function childOf(/*child node*/c, /*parent node*/p){ //returns boolean
while((c=c.parentNode)&&c!==p);
return !!c;
}
..ou comme une ligne (seulement 64 caractères!):
function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}
et jsfiddle here .
sage:childOf(child, parent)
renvoie le booléen true
| false
.
Explication:while
est évalué tant que la condition while est évaluée à true
.
L'opérateur &&
(AND) renvoie ce booléen true/false after en évaluant les côtés gauche et droit, mais uniquement if le côté gauche était vrai (left-hand && right-hand
).
Le côté gauche (de &&
) est: (c=c.parentNode)
.
Ceci affectera d'abord la parentNode
de c
à c
, puis l'opérateur AND évaluera la c
résultante comme un booléen.
Puisque parentNode
retourne null
s'il n'y a plus de parent et que null
est converti en false
, la boucle while s'arrête correctement lorsqu'il n'y a plus de Parents.
Le côté droit (de &&
) est: c!==p
.
L'opérateur de comparaison !==
est 'not exactement égal à'. Ainsi, si le parent de l'enfant n'est pas le parent (spécifié), il est évalué à true
, mais si le parent de l'enfant est le parent, il est évalué à false
.
Donc ifc!==p
est évalué à false, puis l'opérateur &&
renvoie false
sous la forme de la condition while et de la boucle while. (Notez qu’il n’est pas nécessaire de disposer d’un while-body et que le point-virgule ;
de clôture est requis.)
Ainsi, lorsque la boucle while se termine, c
est un noeud (et non null
) lorsqu'il trouve un parent OR, il s’agit de null
(lorsque la boucle est exécutée). à la fin sans trouver un match).
Ainsi, nous avons simplement return
ce fait (converti en valeur booléenne au lieu du nœud) avec: return !!c;
: l'opérateur !
(NOT
opérateur) inverse une valeur booléenne (true
devient false
et vice-versa).!c
convertit c
(nœud ou null) en un booléen avant qu'il ne puisse inverser cette valeur. Donc, ajouter un second !
(!!c
) convertit ce faux back en true (raison pour laquelle un double !!
est souvent utilisé pour "convertir n'importe quoi en booléen" ).
Extra:
Le corps/la charge de la fonction est si petit que, selon les cas (comme quand elle n’est pas souvent utilisée et n’apparaît qu’une seule fois dans le code), on pourrait omettre même la fonction ) et utilisez simplement la boucle while:
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
}
Une autre solution qui n'a pas été mentionnée:
var parent = document.querySelector('.parent');
if (parent.querySelector('.child') !== null) {
// .. it's a child
}
Peu importe que l'élément soit un enfant direct, cela fonctionnera à n'importe quelle profondeur.
Vous pouvez également utiliser la méthode .contains()
:
var parent = document.querySelector('.parent'),
child = document.querySelector('.child');
if (parent.contains(child)) {
// .. it's a child
}
Regardez 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.
Vous pouvez utiliser la méthode includes
var result = parent.contains(child);
ou vous pouvez essayer d'utiliser compareDocumentPosition ()
var result = nodeA.compareDocumentPosition(nodeB);
Le dernier est plus puissant: il renvoie un masque de bits.
Je suis tombé sur un morceau de code merveilleux pour vérifier si un élément est un enfant d'un autre élément. Je dois l'utiliser car IE ne prend pas en charge la méthode de l'élément .contains
. J'espère que cela aidera les autres aussi.
Ci-dessous la fonction:
function isChildOf(childObject, containerObject) {
var returnValue = false;
var currentObject;
if (typeof containerObject === 'string') {
containerObject = document.getElementById(containerObject);
}
if (typeof childObject === 'string') {
childObject = document.getElementById(childObject);
}
currentObject = childObject.parentNode;
while (currentObject !== undefined) {
if (currentObject === document.body) {
break;
}
if (currentObject.id == containerObject.id) {
returnValue = true;
break;
}
// Move up the hierarchy
currentObject = currentObject.parentNode;
}
return returnValue;
}
essaye celui-là:
x = document.getElementById("td35");
if (x.childElementCount > 0) {
x = document.getElementById("LastRow");
x.style.display = "block";
}
else {
x = document.getElementById("LastRow");
x.style.display = "none";
}