Difference between HTMLCollection, NodeLists, and arrays of objects

I've always been confused between HTMLCollections, objects, and arrays when it comes to DOM. For instance...

  1. What is the difference between document.getElementsByTagName("td") and $("td")?
  2. $("#myTable") and $("td") are objects (jQuery objects). Why is console.log also showing the array of DOM elements beside them, and are they not objects and not an array?
  3. What is the elusive "NodeLists" all about, and how do I select one?

Please also provide any interpretation of the below script.

[123,"abc",321,"cba"]=[123,"abc",321,"cba"]
{123:123,abc:"abc",321:321,cba:"cba"}=Object { 123=123, abc="abc", 321=321, more...}
Node= Node { ELEMENT_NODE=1, ATTRIBUTE_NODE=2, TEXT_NODE=3, more...}
document.links= HTMLCollection[a #, a #]
document.getElementById("myTable")= <table id="myTable">
document.getElementsByClassName("myRow")= HTMLCollection[tr.myRow, tr.myRow]
document.getElementsByTagName("td")= HTMLCollection[td, td, td, td]
$("#myTable")= Object[table#myTable]
$("td")= Object[td, td, td, td]




<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>Collections?</title>
<script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
console.log('[123,"abc",321,"cba"]=',[123,"abc",321,"cba"]);
console.log('{123:123,abc:"abc",321:321,cba:"cba"}=',{123:123,abc:"abc",321:321,cba:"cba"});
console.log('Node=',Node);
console.log('document.links=',document.links);
console.log('document.getElementById("myTable")=',document.getElementById("myTable"));
console.log('document.getElementsByClassName("myRow")=',document.getElementsByClassName("myRow"))
console.log('document.getElementsByTagName("td")=',document.getElementsByTagName("td"));
console.log('$("#myTable")=',$("#myTable"));
console.log('$("td")=',$("td"));
});
</script>
</head>


<body>
<a href="#">Link1</a>
<a href="#">Link2</a>
<table id="myTable">
<tr class="myRow"><td>td11</td><td>td12</td></tr>
<tr class="myRow"><td>td21</td><td>td22</td></tr>
</table>
</body>
</html>
82078 次浏览

$("td")是扩展的 jQuery 对象,它有 jQuery 方法,它返回包含 html 对象数组的 jQuery 对象。document.getElementsByTagName("td")是原始 js 方法并返回 NodeList。看看这篇文章

首先,我将解释 NodeListHTMLCollection之间的区别。

两个接口都是 DOM 节点的 收藏品。它们在提供的方法和可以包含的节点类型方面有所不同。虽然 NodeList可以包含任何节点类型,但是 HTMLCollection应该只包含 Element 节点。
HTMLCollection提供与 NodeList相同的方法,另外还提供一个称为 namedItem的方法。

当必须向多个节点提供访问时,总是使用集合,例如,大多数选择器方法(如 getElementsByTagName)返回多个节点或获取对所有子节点(element.childNodes)的引用。

有关更多信息,请参见 DOM4规范-收集

What is the difference between document.getElementsByTagName("td") and $("td")?

getElementsByTagName是 DOM 接口的方法,它接受一个标记名作为输入并返回一个 HTMLCollection(参见 DOM4 specification)。

$("td")大概是 jQuery,它接受任何有效的 CSS/jQuery 选择器并返回一个 jQuery 对象。

标准 DOM 集合和 jQuery 选择之间的最大区别在于,DOM 集合是 一般来说 live (但并非所有方法都返回 live 集合) ,也就是说,如果 DOM 的任何更改受到影响,都会反映在集合中。它们类似于 DOM 树上的 view,而 jQuery 选择是调用该函数时 DOM 树的快照。

Why is console.log also showing the array of DOM elements beside them, and are they not objects and not an array?

jQuery objects are 像数组一样 objects, i.e. they have numeric properties and a length property (keep in mind that arrays are just objects themselves). Browsers tend to display arrays and array-like objects in a special way, like [ ... , ... , ... ].

难以捉摸的“节点列表”是关于什么的,我如何选择一个?

看我的答案的第一部分。你不能 选择NodeLists,他们是一个选择的 结果

据我所知,甚至没有一种方法可以通过编程方式创建 NodeList(即创建一个空的 NodeList并在以后添加节点) ,它们只能由一些 DOM 方法/属性返回。

0. ABC0和 NodeList的区别是什么?

Here are some definitions for you.

DOM Level 1规范-杂项对象定义 :

Interface HTMLCollection

HTMLCollection 是一个节点列表。单个节点可以通过序号索引或节点的名称或 id 属性访问。注意: HTMLDOM 中的集合被假定为活动的,这意味着它们在基础文档更改时会自动更新。

DOM 级别3规范-节点列表

Interface NodeList

NodeList 接口提供对有序节点集合的抽象,而不定义或约束如何实现该集合。DOM 中的 NodeList 对象是活动的。

NodeList 中的项可以通过从0开始的整数索引访问。

因此它们都可以包含实时数据,这意味着 DOM 将在它们的值更新时更新。它们还包含一组不同的函数。

You will note if you inspect the console if you run your scripts that the table DOM element contains both a childNodes NodeList[2] and a children HTMLCollection[1]. Why are they different? Because HTMLCollection can only contain element nodes, NodeList also contains a text node.

enter image description here

1. document.getElementsByTagName("td")$("td")的区别是什么?

document.getElementsByTagName("td")返回一个 DOM 元素数组(一个 NodeList) ,$("td")被称为 jQuery 对象,它的属性 012等等包含来自 document.getElementsByTagName("td")的元素。主要区别在于 jQuery 对象检索起来有点慢,但是可以访问所有方便的 jQuery 函数。

2.$("#myTable")$("td")是对象(jQuery对象)。为什么 console.log也在它们旁边显示 DOM 元素的数组,它们不是对象而不是数组?

它们是将属性 012等设置为 DOM 元素的对象。这里有一个简单的例子: 它是如何工作的:

JsFiddle

    var a = {
1: "first",
2: "second"
}
alert(a[1]);

3. 难以捉摸的“节点列表”是关于什么的? 我如何选择一个?

You have been retrieving them in your code, getElementsByClassName and getElementsByTagName both return NodeLists

NodeList

附加说明

HTMLCollection 和 NodeList 的区别是什么?

HTMLCollection只包含元素节点(tags) ,而 节点列表包含所有的 节点

最重要的节点类型:

  1. 元素节点元素节点
  2. 属性节点
  3. 文本节点
  4. 注释节点

节点类型

元素内的空白被视为文本,而文本被视为节点。

考虑以下几点:

<ul id="myList">
<!-- List items -->
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
<li>List item 5</li>
</ul>

空白: <ul id="myList"> <li>List item</li></ul>

No whitespace: <ul id="myList"><li>List item</li></ul>

Difference between HTMLCollection and a NodeList

< strong > NodeList 对象是 Node 的集合,例如由 x.儿童节点属性或 QuerySelectorAll ()方法返回。在某些情况下,NodeList 是 活下去,这意味着 DOM 中的更改会自动更新集合!例如,Node.chilNodes 是 live:

var c = parent.childNodes; //assume c.length is 2
parent.appendChild(document.createElement('div'));
//now c.length is 3, despite the `c` variable is assigned before appendChild()!!
//so, do not cache the list's length in a loop.

但是在其他一些情况下,NodeList 是 静电干扰,其中 DOM 中的任何更改都不会影响集合的内容。QuerySelectorAll ()返回静态 NodeList。

The HTMLCollection is a live and ordered collection of elements (it is automatically updated when the underlying document is changed). It can be result of properties like as 孩子们 or methods like as GetElementsByTagName (), and 只能有一个 href = “ https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement”rel = “ nofollow noReferrer”> HTMLElement 的 as their items.

HTMLCollection 还通过名称和索引将其成员直接作为属性公开:

var f = document.forms; // this is an HTMLCollection
f[0] === f.item(0) === f.myForm //assume first form id is 'myForm'

HTMLElement 只是节点的一种类型:

Node << HTMLElement inheritance

节点可以是 几种类型。最重要的节点如下:

  • Element (1) : 元素节点,如 <p><div>
  • Attribute (2) : 元素的一个 Attribute。元素属性不再实现 DOM4规范中的 Node 接口!
  • Text (3) : 元素或属性的实际文本。
  • comment (8): A comment node.
  • Document (9) : 文档节点。

所以,一个很大的区别是,HTMLCollection 只包含 HTMLEelement,但 NodeList 也包含注释、空格文本(回车返回字符、空格)。.)等等。按照下面的代码片段检查它:

function printList(x, title) {
console.log("\r\nprinting "+title+" (length="+x.length+"):");
for(var i=0; i<x.length; i++) {
console.log("  "+i+":"+x[i]);
}
}


var elems = document.body.children; //HTMLCollection
var nodes = document.body.childNodes; //NodeList


printList(elems, "children [HTMLCollection]");
printList(nodes, "childNodes [NodeList]");
<div>para 1</div><!-- MyComment -->
<div>para 2</div>

HTMLCollection 和 NodeList 都包含可用于 loop长度属性。不要使用 for... in 或 for each... in 来枚举 NodeList 中的项,因为它们也会枚举其长度和项属性,如果脚本假定它只需要处理元素对象,则会导致错误。还有。.In 并不保证以任何特定的顺序访问属性。

for (var i = 0; i < myNodeList.length; i++) {
var item = myNodeList[i];
}

我们已经讲了很多,但是我们认为用一个例子来解释 HTMLCollectionNodeList之间的差异会有所帮助。

Types of Nodes in DOM

  • 有12种不同的节点类型,它们可能有不同节点类型的子节点:

enter image description here

  • 我们可以使用以下三个属性来检查和查询 DOM 中的节点:

    • nodeType物业
    • nodeName物业
    • nodeValue Property
  • nodeType属性以数字的形式返回指定节点的节点类型。

    • 如果节点是元素节点,则 nodeType属性将返回 1
    • 如果节点是属性节点,则 nodeType属性将返回 2
    • If the node is a text node, the nodeType property will return 3.
    • If the node is a comment node, the nodeType property will return 8.
    • 此属性是只读的。

HTMLCollection 与 NodeList

enter image description here

通过下面的例子,我们可以更清楚地理解 HTMLCollectionNodeList之间的区别。请尝试在您自己的浏览器控制台中检查输出,以便更好地理解。

<ul>
<li>foo</li>
<li>bar</li>
<li>bar</li>
</ul>
// retrieve element using querySelectorAll
const listItems_querySelector = document.querySelectorAll('li');
console.log('querySelector', listItems_querySelector);


// retrieve element using childNodes
const list  = document.querySelector('ul')
const listItems_childNodes = list.childNodes;
console.log('childNodes', listItems_childNodes);
const listItems_children = list.children;
console.log('children', listItems_children);


const listItems_getElementsByTagName = document.getElementsByTagName('li');
console.log('getElementsByTagName', listItems_getElementsByTagName);


console.log('*************************');
console.log('add one list item');
console.log('*************************');
list.appendChild(document.createElement('li'));


console.log('querySelector', listItems_querySelector);
console.log('childNodes', listItems_childNodes);
console.log('children', listItems_children);
console.log('getElementsByTagName', listItems_getElementsByTagName);


console.log('*************************');
console.log('add one more list item');
console.log('*************************');
listItems_getElementsByTagName[0].parentNode.appendChild(document.createElement('li'));


console.log('querySelector', listItems_querySelector);
console.log('childNodes', listItems_childNodes);
console.log('children', listItems_children);
console.log('getElementsByTagName', listItems_getElementsByTagName);