获取子节点的最佳方式

2022-08-30 00:24:47

我想知道,JavaScript提供了多种方法从任何元素中获取第一个子元素,但哪个是最好的?最好的,我的意思是:在行为方面,最跨浏览器兼容,最快,最全面和可预测。我用作别名的方法/属性列表:

var elem = document.getElementById('container');
var child = elem.children[0];
var child = elem.firstElementChild; // == children[0]

这适用于两种情况:

var child = elem.childNodes[0]; // or childNodes[1], see below

这是在形式或迭代的情况下。如果可能遇到文本元素:<div>

var child = elem.childNodes; // treat as NodeList
var child = elem.firstChild;

据我所知,使用 来自 的 NodeList 并使用 。我基于MDN参考的假设:firstChildchildNodesfirstElementChildchildren

childNode是对元素节点的第一个子元素的引用,如果没有子元素,则为引用。null

我猜想,就速度而言,差异(如果有的话)几乎为零,因为实际上是对 的引用,并且对象已经在内存中了。firstElementChildchildren[0]children

扔给我的,是物体。我用它来查看表格元素中的表单。虽然列出了所有表单元素,但似乎还包括 HTML 代码中的空格:childNodeschildrenchildNodes

console.log(elem.childNodes[0]);
console.log(elem.firstChild);

两个日志<TextNode textContent="\n ">

console.log(elem.childNodes[1]);
console.log(elem.children[0]);
console.log(elem.firstElementChild);

所有日志 ....怎么会这样?我知道一个对象允许我使用“原始”HTML代码,而另一个对象则坚持使用DOM,但该元素似乎在两个级别上都有效。<input type="text">childNodes

回到我最初的问题,我的猜测是:如果我想要最全面的对象,那就是要走的路,但是由于它的全面性,它可能不是最可预测的,因为它在任何给定时刻都返回我想要/期望的元素。在这种情况下,跨浏览器支持也可能被证明是一个挑战,尽管我可能是错的。childNodes

谁能澄清手头物体之间的区别?如果有速度差,无论多么微不足道,我也想知道。如果我看到这一切都错了,请随时教育我。


PS:拜托,拜托,我喜欢JavaScript,所以是的,我想处理这种事情。像“jQuery为你处理这个”这样的答案不是我想要的,因此没有标签。


答案 1

听起来你想得太多了。您已经观察到 和 之间的区别,即包含所有节点,包括完全由空格组成的文本节点,而 只是作为元素的子节点的集合。这就是它的全部内容。childNodeschildrenchildNodeschildren

这两个集合都没有什么不可预测的,尽管有几个问题需要注意:

  • IE <= 8 不包含仅空格的文本节点,而其他浏览器则包含childNodes
  • IE <= 8 包含注释节点,而其他浏览器只有元素children

children,朋友只是方便,呈现了DOM的过滤视图,仅限于元素。firstElementChild


答案 2

firstElementChild 在 IE<9 中可能不可用(仅限 firstChild)

在 IE<9 上,firstChild 是第一个ElementChild,因为 MS DOM (IE<9) 不存储空文本节点。但是,如果您在其他浏览器上这样做,它们将返回空的文本节点...

我的解决方案

child=(elem.firstElementChild||elem.firstChild)

这将给第一个孩子,甚至在IE<9