Як перевірити, чи є в елемента JavaScript якісь діти?


103

Просте запитання, у мене є елемент, через який я захоплююсь .getElementById (). Як перевірити, чи є у нього діти?

Відповіді:


194

Кілька способів:

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

або hasChildNodes()функція:

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

або lengthвласність childNodes:

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

Якщо ви хочете знати лише про дочірні елементи (на відміну від текстових вузлів, атрибутивних вузлів тощо) у всіх сучасних браузерах (а IE8 - насправді навіть IE6), ви можете зробити це: (дякую Флоріану !)

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

Це залежить від childrenвласності, яка не була визначена в DOM1 , DOM2 , або DOM3 , але має практично універсальну підтримку. (Він працює в IE6 та новіших версіях, а також у Chrome, Firefox та Opera, щонайменше , ще в листопаді 2012 року, коли це було написано спочатку.) Якщо ви підтримуєте старі мобільні пристрої, не забудьте перевірити їх підтримку.

Якщо вам не потрібна підтримка IE8 та попередньої версії, ви також можете зробити це:

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

Це спирається на firstElementChild. Мовляв children, він також не був визначений у DOM1-3, але на відміну від childrenнього не додавали до IE до IE9.

Якщо ви хочете дотримуватися чогось, визначеного в DOM1 (можливо, вам доведеться підтримувати дійсно неясні браузери), вам доведеться зробити більше роботи:

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

Все це є частиною DOM1 і майже повсюдно підтримується.

Це було б легко зафіксувати у функції, наприклад:

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

О, я не розумів, що childrenдодано лише в DOM4. Знаючи, що його підтримують у будь-якому відомому браузері, я подумав, що це майже DOM0 / 1.
Флоріан Маргаїн

як я можу перевірити, чи є у когось divелемент, що divмає конкретний клас скажімо xyz?
Pooja Desai

firstChild та hasChildNodes повертають будь-який вузол, не лише дітей (nodeType == 1). Ви повинні це виправити. ;-)
Адріан Мейр

1
Ніколи не бачив умови циклу, як for (child = element.firstChild; child; child = child.nextSibling ), проголосував. Дякую TJ
NiCk Newman

2
@Aaron: Це цілком можливо , element.firstChildщоб бути не- nullколи element.children.lengthє 0: firstChildі таке ставлення до вузлів , включаючи елементи, текстові вузли, коментувати замітки, і т.п.; childrenце суто список дітей- елементів . У сучасних браузерах ви можете використовувати firstElementChildзамість цього.
TJ Crowder

8

Як згадує slashnick & bobince, hasChildNodes()повернеться вірно для пробілів (текстові вузли). Однак я не хотів такої поведінки, і це працювало на мене :)

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

Редагувати : для тієї ж функціональності це краще рішення:

 element.children.length > 0

children[]- це підмножина childNodes[], що містить лише елементи.

Сумісність


2

Ви можете перевірити, чи є в елементі дочірні вузли element.hasChildNodes(). Остерігайтеся в Mozilla це повернеться істиною, якщо після тегу буде пробіл, тому вам потрібно буде перевірити тип тегу.

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


7
Не тільки в Mozilla. Це правильна поведінка; це IE, що помиляється
bobince

2

Ви також можете зробити наступне:

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

Для цього використовується метод trim () для обробки порожніх елементів, які мають лише пробіли (у цьому випадку hasChildNodesповертає істину) як порожні.

Демонстрація JSBin


Як це поводиться з коментарями HTML?
Віктор Заманян

1

Пізній, але фрагмент документа може бути вузлом:

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

Дивіться:
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

Функція багаторазового використання isEmpty( <selector> ).
Ви також можете запустити його до колекції елементів (див. Приклад)

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>

повертає true(і виходить із циклу), як тільки один елемент має будь-який вміст поруч із пробілами чи новими рядками.


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

Будь ласка, не просто надайте рішення лише для коду. Крім того, чому ви прокоментували код там?
Лі Тейлор

Downvote: Цей код незрозумілий, частина коду зайва, немає коментарів чи пояснень, і він виглядає як копія / минуле. Також частина XML тут не має нічого спільного.
Адріан Мейр

2
Що це за божевілля?
NiCk Newman
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.