¿Cómo verificar si el elemento tiene hijos en Javascript?


103

Pregunta simple, tengo un elemento que estoy agarrando .getElementById (). ¿Cómo verifico si tiene hijos?

Respuestas:


194

Un par de formas:

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

o la hasChildNodes()función:

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

o lengthpropiedad de childNodes:

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

Si solo desea conocer los elementos secundarios (a diferencia de los nodos de texto, nodos de atributos, etc.) en todos los navegadores modernos (e IE8, de hecho, incluso IE6) puede hacer esto: (¡gracias Florian !)

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

Que se basa en la childrenpropiedad, que no estaba definido en DOM1 , DOM2 , o DOM3 , pero que cuenta con el apoyo casi universal. (Funciona en IE6 y versiones posteriores y Chrome, Firefox y Opera al menos desde noviembre de 2012, cuando se escribió originalmente). Si es compatible con dispositivos móviles más antiguos, asegúrese de buscar soporte.

Si no necesita IE8 y soporte anterior, también puede hacer esto:

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

Eso depende firstElementChild. Por childrenejemplo, tampoco se definió en DOM1-3, pero a diferencia de childrenesto, no se agregó a IE hasta IE9.

Si desea ceñirse a algo definido en DOM1 (tal vez tenga que admitir navegadores realmente oscuros), debe trabajar más:

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

Todo eso es parte de DOM1 y tiene soporte casi universal.

Sería fácil resumir esto en una función, por ejemplo:

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;
}

Oh, no me di cuenta de que childrensolo se agregó en DOM4. Sabiendo que era compatible con cualquier navegador conocido, pensé que era más o menos DOM0 / 1.
Florian Margaine

¿Cómo verifico si hay algún divelemento que divtenga una clase específica xyz?
Pooja Desai

firstChild y hasChildNodes devuelven cualquier nodo, no solo hijos (nodeType == 1). Deberías corregir eso. ;-)
Adrian Maire

1
Nunca vi una condición de bucle como for (child = element.firstChild; child; child = child.nextSibling ), votó. Gracias TJ
NiCk Newman

2
@Aaron: Es completamente posible element.firstChildque no sea nullcuando element.children.lengthes 0: firstChildy esto se relaciona con nodos, incluidos elementos, nodos de texto, notas de comentarios, etc .; childrenes puramente una lista de elementos secundarios. En los navegadores modernos, puede usar firstElementChilden su lugar.
TJ Crowder

8

Como mencionan slashnick & bobince, hasChildNodes()devolverá verdadero para los espacios en blanco (nodos de texto). Sin embargo, no quería este comportamiento, y esto funcionó para mí :)

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

Editar : para la misma funcionalidad, esta es una mejor solución:

 element.children.length > 0

children[]es un subconjunto de childNodes[], que contiene solo elementos.

Compatibilidad


2

Puede verificar si el elemento tiene nodos secundarios element.hasChildNodes(). Tenga cuidado en Mozilla, esto devolverá verdadero si hay un espacio en blanco después de la etiqueta, por lo que deberá verificar el tipo de etiqueta.

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


7
No solo en Mozilla. Este es el comportamiento correcto; es IE el que se equivoca.
bobince

2

También puede hacer lo siguiente:

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

Esto usa el método trim () para tratar los elementos vacíos que solo tienen espacios en blanco (en cuyo caso hasChildNodesdevuelve verdadero) como si estuvieran vacíos.

Demostración de JSBin


¿Cómo se comporta esto con los comentarios HTML?
Victor Zamanian

1

Tarde, pero el fragmento del documento podría ser un nodo:

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;
}

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



0

Una isEmpty( <selector> )función reutilizable .
También puede ejecutarlo hacia una colección de elementos (ver ejemplo)

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>

devuelve true(y sale del bucle) tan pronto como un elemento tenga algún tipo de contenido al lado de espacios o líneas nuevas.


-9
<script type="text/javascript">

function uwtPBSTree_NodeChecked(treeId, nodeId, bChecked) 
{
    //debugger;
    var selectedNode = igtree_getNodeById(nodeId);
    var ParentNodes = selectedNode.getChildNodes();

    var length = ParentNodes.length;

    if (bChecked) 
    {
/*                if (length != 0) {
                    for (i = 0; i < length; i++) {
                        ParentNodes[i].setChecked(true);
                    }
    }*/
    }
    else 
    {
        if (length != 0) 
        {
            for (i = 0; i < length; i++) 
            {
                ParentNodes[i].setChecked(false);
            }
        }
    }
}
</script>

<ignav:UltraWebTree ID="uwtPBSTree" runat="server"..........>
<ClientSideEvents NodeChecked="uwtPBSTree_NodeChecked"></ClientSideEvents>
</ignav:UltraWebTree>

Por favor, no proporcione soluciones de solo código. Además, ¿por qué ha comentado el código allí?
Lee Taylor

Votar en contra: este código es oscuro, parte del código es innecesario, no hay comentarios ni explicaciones y parece una copia / pasado. Además, la parte XML no tiene nada que ver aquí.
Adrian Maire

2
¿Qué es esta locura?
NiCk Newman
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.