Как проверить, есть ли у элемента дочерние элементы в Javascript?


104

Простой вопрос, у меня есть элемент, который я хватаю .getElementById (). Как мне проверить, есть ли у него дети?

Ответы:


196

Пару способов:

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.
Florian Margaine

как я могу проверить, есть ли у какого-либо divэлемента divопределенный класс xyz?
Пуджа Десаи,

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()вернет true для пробелов (текстовых узлов). Однако я не хотел такого поведения, и это сработало для меня :)

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

Изменить : для той же функциональности это лучшее решение:

 element.children.length > 0

children[]является подмножеством childNodes[], содержащим только элементы.

Совместимость


2

Вы можете проверить, есть ли у элемента дочерние узлы element.hasChildNodes(). Будьте осторожны в Mozilla, это вернет true, если после тега стоит пробел, поэтому вам нужно будет проверить тип тега.

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


7
Не только в Mozilla. Это правильное поведение; это IE ошибается.
bobince

2

Вы также можете сделать следующее:

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

Он использует метод trim () для обработки пустых элементов, которые имеют только пробелы (в этом случае hasChildNodesвозвращает true) как пустые.

Демо 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>

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

Голос против: этот код неясен, часть кода не обязательна, нет комментариев или объяснений, и он выглядит как копия / прошлое. Также XML-часть здесь не при чем.
Адриан Мэйр,

2
Что это за безумие?
NiCk Newman
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.