一个简单的问题,我通过 .getElementById()
获取了一个元素。如何检查它是否有任何子元素?
一个简单的问题,我通过 .getElementById()
获取了一个元素。如何检查它是否有任何子元素?
有几种方法:
if (element.firstChild) {
// It has at least one
}
或者使用 hasChildNodes()
函数:
if (element.hasChildNodes()) {
// It has at least one
}
childNodes
的 length
属性:if (element.childNodes.length > 0) { // Or just `if (element.childNodes.length)`
// It has at least one
}
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年11月,当时它最初编写。)如果需要支持旧的移动设备,请确保检查支持情况。
如果不需要支持IE8及以下版本,则还可以这样做:
if (element.firstElementChild) {
// It has at least one element as a child
}
这取决于 firstElementChild
。与children
一样,它在DOM1-3中也没有定义,但与children
不同的是,直到IE9才将其添加到IE中。childElementCount
也是如此:
if (element.childElementCount !== 0) {
// It has at least one element as a child
}
如果您想坚持使用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;
}
正如slashnick和bobince所提到的,hasChildNodes()
会对空格(文本节点)返回true。然而,我不想要这种行为,而这对我起作用了 :)
element.getElementsByTagName('*').length > 0
编辑:为了实现相同的功能,这是一个更好的解决方案:
element.children.length > 0
children[]
是childNodes[]
的子集,仅包含元素。
if (element.innerHTML.trim() !== '') {
// It has at least one
}
这里使用trim()方法将仅包含空格字符的空元素视为空(此时hasChildNodes
会返回true)。
注意:上述方法并不过滤掉注释。(因此,注释将被视为子元素)
为了过滤掉注释,我们可以利用只读的Node.nodeType属性,其中Node.COMMENT_NODE
(例如<!--...-->
)具有常量值-8。
if (element.firstChild?.nodeType !== 8 && element.innerHTML.trim() !== '' {
// It has at least one
}
let divs = document.querySelectorAll('div');
for(element of divs) {
if (element.firstChild?.nodeType !== 8 && element.innerHTML.trim() !== '') {
console.log('has children')
} else { console.log('no children') }
}
<div><span>An element</span>
<div>some text</div>
<div> </div> <!-- whitespace -->
<div><!-- A comment --></div>
<div></div>
element.firstElementChild
可能是最简单的方法 :) - Danieldelement.hasChildNodes()
来检查元素是否具有子节点。请注意,在Mozilla中,如果标签后面有空格,则此方法将返回true,因此您需要验证标签类型。
https://developer.mozilla.org/En/DOM/Node.hasChildNodes
尝试使用childElementCount 属性:
if ( element.childElementCount !== 0 ){
alert('i have children');
} else {
alert('no kids here');
}
虽然有点晚,但文档片段也可以是一个节点:
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;
}
See:
https://github.com/k-gun/so/blob/master/so.dom.js#L42
https://github.com/k-gun/so/blob/master/so.dom.js#L741
一个可重复使用的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
(并退出循环)。
<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>
children
只是在DOM4中添加的。知道它被任何已知的浏览器支持,我以为它几乎是DOM0 / 1的一部分。 - Florian Margainefor (child = element.firstChild; child; child = child.nextSibling )
这样的循环条件,点赞。感谢 T.J. - NiCk Newmanelement.children.length
为0
时,element.firstChild
仍然可能是非空的。因为firstChild
和其他类似属性是与节点相关的,包括元素、文本节点、注释节点等;而children
则纯粹是一个元素子节点列表。在现代浏览器中,您可以使用firstElementChild
来代替。 - T.J. CrowderchildElementCount
这个属性。查了一下资料,发现childElementCount
只计算子元素的数量,而不是所有子节点(就像children.length
一样)。也许你曾经试图使用firstChild
或类似的方法来“检测”,但元素包含文本节点或注释节点(而不是元素):-) - T.J. Crowder