Jak sprawdzić, czy element ma jakieś dzieci w JavaScript?


104

Proste pytanie, mam element, przez który chwytam .getElementById (). Jak sprawdzić, czy ma dzieci?

Odpowiedzi:


195

Na kilka sposobów:

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

lub hasChildNodes()funkcja:

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

lub lengthwłasność childNodes:

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

Jeśli chcesz wiedzieć tylko o elementach potomnych (w przeciwieństwie do węzłów tekstowych, węzłów atrybutów itp.) We wszystkich nowoczesnych przeglądarkach (i IE8 - w rzeczywistości nawet IE6), możesz to zrobić: (dziękuję Florian !)

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

Który opiera się na childrennieruchomości, która nie została zdefiniowana w DOM1 , DOM2 , lub DOM3 , ale który ma niemal powszechnego poparcia. (Działa w IE6 i nowszych oraz Chrome, Firefox i Opera przynajmniej od listopada 2012 r., Kiedy to zostało pierwotnie napisane). Jeśli obsługujesz starsze urządzenia mobilne, sprawdź, czy są obsługiwane.

Jeśli nie potrzebujesz obsługi IE8 i wcześniejszych wersji, możesz również zrobić to:

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

To zależy od firstElementChild. Podobnie jak childrennie zostało zdefiniowane w DOM1-3, ale w przeciwieństwie do childrentego nie zostało dodane do IE aż do IE9.

Jeśli chcesz trzymać się czegoś zdefiniowanego w DOM1 (może musisz obsługiwać naprawdę mało znane przeglądarki), musisz wykonać więcej pracy:

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

Wszystko to jest częścią DOM1 i jest prawie powszechnie obsługiwane.

Byłoby łatwo zawrzeć to w funkcji, np .:

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

Och, nie zdawałem sobie sprawy, że childrenzostało dodane tylko w DOM4. Wiedząc, że jest obsługiwany w każdej znanej przeglądarce, pomyślałem, że to prawie DOM0 / 1.
Florian Margaine

jak sprawdzić, czy któryś z divelementów divma coś do powiedzenia xyz?
Pooja Desai

firstChild i hasChildNodes zwracają dowolny węzeł, nie tylko dzieci (nodeType == 1). Powinieneś to poprawić. ;-)
Adrian Maire

1
Nigdy nie widziałem warunku pętli, takiego jak for (child = element.firstChild; child; child = child.nextSibling )głosowanie. Dzięki TJ
NiCk Newman

2
@Aaron: Całkowicie możliwe jest, element.firstChildaby nie być - nullkiedy element.children.lengthjest 0: firstChildi dotyczy to węzłów, w tym elementów, węzłów tekstowych, uwag w komentarzach itp .; childrenjest czystą listą elementów potomnych. W nowoczesnych przeglądarkach możesz firstElementChildzamiast tego użyć .
TJ Crowder

8

Jak wspomina slashnick & bobince, hasChildNodes()zwróci wartość true dla białych znaków (węzłów tekstowych). Jednak nie chciałem takiego zachowania i to zadziałało dla mnie :)

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

Edycja : dla tej samej funkcjonalności jest to lepsze rozwiązanie:

 element.children.length > 0

children[]jest podzbiorem childNodes[]zawierającym tylko elementy.

Zgodność



2

Możesz też wykonać następujące czynności:

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

Używa metody trim () do traktowania pustych elementów, które mają tylko białe spacje (w takim przypadku hasChildNodeszwraca wartość true), jako pustych.

JSBin Demo


Jak to się zachowuje w przypadku komentarzy HTML?
Victor Zamanian

1

Spóźniony, ale fragment dokumentu może być węzłem:

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

Zobacz:
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

Funkcja wielokrotnego użytku isEmpty( <selector> ).
Możesz również uruchomić go w kierunku zbioru elementów (patrz przykład)

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>

zwraca true(i wychodzi z pętli), gdy tylko jeden element ma jakąkolwiek zawartość poza spacjami lub znakami nowej linii.


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

Proszę nie tylko dostarczać rozwiązań opartych na samym kodzie. Poza tym, dlaczego zakomentowałeś tam kod?
Lee Taylor,

Głos przeciw: ten kod jest niejasny, część kodu jest niepotrzebna, nie ma komentarzy ani wyjaśnień i wygląda jak kopia / przeszłość. Również część XML nie ma tu nic do roboty.
Adrian Maire

2
Co to za szaleństwo?
NiCk Newman,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.