Como verificar se o elemento possui algum filho em Javascript?

103

Pergunta simples, tenho um elemento que estou captando .getElementById (). Como posso verificar se tem filhos?

David
fonte

Respostas:

194

Algumas maneiras:

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

ou a hasChildNodes()função:

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

ou a lengthpropriedade de childNodes:

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

Se você quiser saber apenas sobre os elementos filho (em oposição aos nós de texto, nós de atributos, etc.) em todos os navegadores modernos (e IE8 - na verdade, até mesmo IE6), você pode fazer isso: (obrigado Florian !)

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

Que se baseia na childrenpropriedade, que não foi definido no DOM1 , DOM2 , ou DOM3 , mas que tem apoio quase universal. (Funciona no IE6 e superior e Chrome, Firefox e Opera pelo menos desde novembro de 2012, quando foi originalmente escrito.) Se for compatível com dispositivos móveis mais antigos, certifique-se de verificar o suporte.

Se você não precisa do IE8 e do suporte anterior, também pode fazer o seguinte:

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

Isso depende firstElementChild. Por exemplo children, também não foi definido no DOM1-3, mas, ao contrário children, não foi adicionado ao IE até o IE9.

Se você quiser manter algo definido em DOM1 (talvez tenha que oferecer suporte a navegadores realmente obscuros), você terá que trabalhar mais:

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

Tudo isso faz parte do DOM1 e tem suporte quase universal.

Seria fácil resumir isso em uma função, por exemplo:

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;
}
TJ Crowder
fonte
Ah, não sabia que childrensó foi adicionado no DOM4. Sabendo que era compatível com qualquer navegador conhecido, achei que era praticamente DOM0 / 1.
Florian Margaine
como faço para verificar se algum divtem elemento divcom classe específica dizer xyz?
Pooja Desai
firstChild e hasChildNodes retornam qualquer nó, não apenas filhos (nodeType == 1). Você deve corrigir isso. ;-)
Adrian Maire
1
Nunca vi uma condição de loop como for (child = element.firstChild; child; child = child.nextSibling ), votou. Obrigado TJ
NiCk Newman
2
@Aaron: É inteiramente possível element.firstChildnão ser nullquando element.children.lengthé 0: firstChilde está relacionado a nós, incluindo elementos, nós de texto, notas de comentários, etc .; childrené puramente uma lista de filhos de elementos . Em navegadores modernos, você pode usar firstElementChild.
TJ Crowder
8

Como slashnick & bobince menciona, hasChildNodes()retornará true para espaços em branco (nós de texto). No entanto, eu não queria esse comportamento e funcionou para mim :)

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

Editar : para a mesma funcionalidade, esta é uma solução melhor:

 element.children.length > 0

children[]é um subconjunto de childNodes[], contendo apenas elementos.

Compatibilidade

c24w
fonte
2

Você pode verificar se o elemento tem nós filhos element.hasChildNodes() . Cuidado no Mozilla, isso retornará verdadeiro se houver um espaço em branco após a tag, então você precisará verificar o tipo de tag.

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

Slashnick
fonte
7
Não apenas no Mozilla. Este é o comportamento correto; é o IE que está errado.
bobince
2

Você também pode fazer o seguinte:

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

Isso usa o método trim () para tratar os elementos vazios que têm apenas espaços em branco (nesse caso, hasChildNodesretorna verdadeiro) como sendo vazios.

JSBin Demo

Danield
fonte
Como isso se comporta com comentários HTML?
Victor Zamanian
1

Atrasado, mas o fragmento do documento pode ser um nó:

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

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

K-Gun
fonte
1

Experimente a propriedade childElementCount :

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

Uma isEmpty( <selector> )função reutilizável .
Você também pode executá-lo em uma coleção de elementos (veja o exemplo)

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>

retorna true(e sai do loop) assim que um elemento tiver qualquer tipo de conteúdo além de espaços ou novas linhas.

Roko C. Buljan
fonte
-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>
Govind Kumar Sahu
fonte
Não forneça apenas soluções apenas de código. Além disso, por que você comentou o código lá?
Lee Taylor
Downvote: Este código é obscuro, parte do código não é necessária, não há comentários ou explicação e parece uma cópia / passado. Além disso, a parte XML não tem nada a ver aqui.
Adrian Maire
2
O que é essa loucura?
NiCk Newman