如何检查元素在Javascript中是否有任何子元素?


103

一个简单的问题,我有一个要通过抓取的元素.getElementById ()。我如何检查是否有孩子?

Answers:


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)上的子元素(与文本节点,属性节点等相对),则可以执行以下操作:(谢谢Florian!)

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

这依赖于children房地产,这是不是在定义DOM1DOM2 DOM3,但其中有接近普遍支持。(它至少可以早于最初编写时的2012年11月在IE6及更高版本以及Chrome,Firefox和Opera中运行。)如果支持较旧的移动设备,请确保检查支持。

如果不需要IE8和更早的支持,也可以这样做:

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

那要靠firstElementChild。像一样children,它也没有在DOM1-3中定义,但是与之不同的children是,直到IE9才将其添加到IE中。

如果要坚持使用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 '11年

我如何检查是否divdiv具有特定类的元素说xyz
Pooja Desai

firstChild和hasChildNodes返回任何节点,不仅返回子节点(nodeType == 1)。您应该纠正它。;-)
Adrian Maire 2013年

1
从未见过像这样的循环条件for (child = element.firstChild; child; child = child.nextSibling )。感谢TJ
NiCk Newman

2
@Aaron:它是完全有可能element.firstChild成为非nullelement.children.length0firstChild并且这种涉及的节点,包括元素,文本节点,注释的注释等; children纯粹是元素子级的列表。在现代浏览器上,您可以firstElementChild改用。
TJ Crowder

8

如slashnick和bobince所述,hasChildNodes()对于空白(文本节点)将返回true。但是,我不想这种行为,这对我有用:)

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

编辑:对于相同的功能,这是一个更好的解决方案:

 element.children.length > 0

children[]是的子集childNodes[],仅包含元素。

兼容性



2

您还可以执行以下操作:

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

这使用trim()方法将只有空格(在这种情况下hasChildNodes返回true)的空元素视为空。

JSBin演示


HTML注释如何处理?
Victor Zamanian

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部分与此无关。
Adrian Maire 2013年

2
这是什么疯狂?
NiCk Newman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.