【发布时间】:2011-01-10 19:45:41
【问题描述】:
简单的问题,我有一个通过.getElementById () 抓取的元素。我如何检查它是否有孩子?
【问题讨论】:
标签: javascript dom
简单的问题,我有一个通过.getElementById () 抓取的元素。我如何检查它是否有孩子?
【问题讨论】:
标签: javascript dom
几种方法:
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
}
如果您只想了解所有现代浏览器(以及 IE8,甚至 IE6)上的子 元素(相对于文本节点、属性节点等),您可以这样做:(谢谢Florian!)
if (element.children.length > 0) { // Or just `if (element.children.length)`
// It has at least one element as a child
}
这依赖于 children 属性,该属性未在 DOM1、DOM2、 或 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 中。这同样适用于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;
}
【讨论】:
children 只是在 DOM4 中添加的。知道任何已知浏览器都支持它,我认为这几乎是 DOM0/1。
div 具有元素div 具有特定类说xyz?
for (child = element.firstChild; child; child = child.nextSibling ) 这样的循环条件,已投票。谢谢 T.J.
element.children.length 是0: firstChild 时,element.firstChild 完全有可能成为非null:firstChild 等与 nodes 相关,包括元素、文本节点、注释注释等; children 纯粹是 element 子元素的列表。在现代浏览器上,您可以改用firstElementChild。
childElementCount。查看它,请注意 childElementCount 只计算子 元素,而不是所有子节点(就像 children.length 一样)。也许您正试图使用firstChild 或类似名称“检测”,并且该元素包含文本节点或注释节点(但不包含元素)。 :-)
正如 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)视为空。
注意:上述方法没有过滤掉cmets。 (所以评论会将孩子归类)
为了过滤掉 cmets,我们可以使用只读的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 可能是最简单的方法:)
您可以检查元素是否有子节点element.hasChildNodes()。请注意,在 Mozilla 中,如果标签后面是空格,这将返回 true,因此您需要验证标签类型。
【讨论】:
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;
}
见:
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>
【讨论】: