web-dev-qa-db-fra.com

Comment vérifier si l'élément a des enfants en Javascript?

Question simple, j'ai un élément que je saisis via .getElementById (). Comment puis-je vérifier s'il a des enfants?

86
David

Quelques façons:

if (element.firstChild) {
    // It has at least one
}

ou la fonction hasChildNodes():

if (element.hasChildNodes()) {
    // It has at least one
}

ou la propriété length de childNodes:

if (element.childNodes.length > 0) { // Or just `if (element.childNodes.length)`
    // It has at least one
}

Si vous voulez seulement connaître enfant éléments (par opposition aux nœuds de texte, d'attributs, etc.) sur tous les navigateurs modernes (et IE8 - en fait, même IE6), vous pouvez le faire: (merci Florian !)

if (element.children.length > 0) { // Or just `if (element.children.length)`
    // It has at least one element as a child
}

Cela repose sur la propriété children , qui n'était pas définie dans DOM1 , DOM2 , ouDOM3 , mais qui dispose d'un support quasi universel. (Cela fonctionne dans IE6 et versions ultérieures, ainsi que dans Chrome, Firefox et Opera avec less dès novembre 2012, date à laquelle cela a été écrit.) Si vous utilisez des appareils mobiles plus anciens, assurez-vous de rechercher une assistance.

Si vous n'avez pas besoin du support IE8 et antérieur, vous pouvez également le faire:

if (element.firstElementChild) {
    // It has at least one element as a child
}

Cela repose sur firstElementChild . Comme children, il n'était pas non plus défini dans DOM1-3, mais contrairement à children, il n'a pas été ajouté à IE jusqu'à IE9.

Si vous voulez vous en tenir à quelque chose défini dans DOM1 (peut-être que vous devez supporter des navigateurs vraiment obscurs), vous devez faire plus de travail:

var hasChildElements, child;
hasChildElements = false;
for (child = element.firstChild; child; child = child.nextSibling) {
    if (child.nodeType == 1) { // 1 == Element
        hasChildElements = true;
        break;
    }
}

Tout cela fait partie de DOM1 et est presque universellement supporté.

Il serait facile de résumer cela dans une fonction, par exemple:

function hasChildElement(Elm) {
    var child, rv;

    if (Elm.children) {
        // Supports `children`
        rv = Elm.children.length !== 0;
    } else {
        // The hard way...
        rv = false;
        for (child = element.firstChild; !rv && child; child = child.nextSibling) {
            if (child.nodeType == 1) { // 1 == Element
                rv = true;
            }
        }
    }
    return rv;
}
156
T.J. Crowder

Comme mentionné par slashnick & bobince, hasChildNodes() retournera true pour les espaces (nœuds de texte). Cependant, je ne voulais pas ce comportement, et cela a fonctionné pour moi :)

element.getElementsByTagName('*').length > 0

Edit: pour la même fonctionnalité, c'est une meilleure solution:

 element.children.length > 0

children[] est un sous-ensemble de childNodes[], contenant uniquement des éléments.

Compatibilité

5
c24w

Vous pouvez vérifier si l'élément a des nœuds enfants element.hasChildNodes(). Attention, dans Mozilla, cela retournera la valeur true s'il y a un espace après la balise. Vous devrez donc vérifier le type de balise.

https://developer.mozilla.org/En/DOM/Node.hasChildNodes

2
slashnick

En retard mais fragment de document pourrait être un nœud:

function hasChild(el){
    var child = el && el.firstChild;
    while (child) {
        if (child.nodeType === 1 || child.nodeType === 11) {
            return true;
        }
        child = child.nextSibling;
    }
    return false;
}
// or
function hasChild(el){
    for (var i = 0; el && el.childNodes[i]; i++) {
        if (el.childNodes[i].nodeType === 1 || el.childNodes[i].nodeType === 11) {
            return true;
        }
    }
    return false;
}

Voir:
https://github.com/k-gun/so/blob/master/so.dom.js#L42
https://github.com/k-gun/so/blob/master/so.dom.js#L741

1
K-Gun

Vous pouvez également faire ce qui suit:

if (element.innerHTML.trim() !== '') {
    // It has at least one
} 

Ceci utilise la méthode trim () pour traiter les éléments vides ne contenant que des espaces (dans ce cas, hasChildNodes renvoie true) comme étant vides.

Démo JSBin

1
Danield

Essayez la propriété childElementCount :

if ( element.childElementCount !== 0 ){
      alert('i have children');
} else {
      alert('no kids here');
}
0
Stirling

Une fonction isEmpty( <selector> ) réutilisable.
Vous pouvez aussi le lancer vers une collection d’éléments (voir exemple)

const isEmpty = sel =>
    ![... document.querySelectorAll(sel)].some(el => el.innerHTML.trim() !== "");

console.log(
  isEmpty("#one"), // false
  isEmpty("#two"), // true
  isEmpty(".foo"), // false
  isEmpty(".bar")  // true
);
<div id="one">
 foo
</div>

<div id="two">
 
</div>

<div class="foo"></div>
<div class="foo"><p>foo</p></div>
<div class="foo"></div>

<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>

renvoie true (et quitte la boucle) dès qu'un élément a un contenu quelconque à côté des espaces ou des nouvelles lignes.

0
Roko C. Buljan