Question simple, j'ai un élément que je saisis via .getElementById ()
. Comment puis-je vérifier s'il a des enfants?
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;
}
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.
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.
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
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.
Essayez la propriété childElementCount :
if ( element.childElementCount !== 0 ){
alert('i have children');
} else {
alert('no kids here');
}
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.