HTMLCollection,NodeLists和对象数组之间的区别

use*_*531 79 javascript jquery dom

在DOM方面,我一直对HTMLCollections,对象和数组感到困惑.例如...

  1. document.getElementsByTagName("td")和之间有什么区别$("td")
  2. $("#myTable")并且$("td")是对象(jQuery对象).为什么console.log还会在它们旁边显示DOM元素数组,它们不是对象而不是数组?
  3. 什么是难以捉摸的"NodeLists",我如何选择一个?

还请提供以下脚本的任何解释.

谢谢

[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>
Run Code Online (Sandbox Code Playgroud)

Fel*_*ing 101

首先,我将解释之间的差异NodeListHTMLCollection.

两个接口是集合 DOM节点.它们在提供的方法和它们可以包含的节点类型方面有所不同.虽然a NodeList可以包含任何节点类型,但是HTMLCollection应该只包含Element节点.
An HTMLCollection提供与a NodeList和另外一种方法相同的方法namedItem.

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

有关更多信息,请查看DOM4规范 - 集合.

document.getElementsByTagName("td")和之间有什么区别$("td")

getElementsByTagName是DOM接口的方法.它接受标记名称作为输入并返回HTMLCollection(参见DOM4规范).

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

标准DOM集合和jQuery选择之间的最大区别在于DOM集合通常是实时的(并非所有方法都返回实时集合),即如果受到影响,对DOM的任何更改都会反映在集合中.它们就像DOM树上的视图,而jQuery选择是调用函数时DOM树的快照.

为什么console.log还会在它们旁边显示DOM元素数组,它们不是对象而不是数组?

jQuery对象是类似于数组的对象,即它们具有数字属性和length属性(请记住,数组本身就是对象).浏览器倾向于以特殊方式显示数组和类似数组的对象,例如[ ... , ... , ... ].

什么是难以捉摸的"NodeLists",我如何选择一个?

请参阅我的答案的第一部分.你不能选择 NodeList s,它们是选择结果.

据我所知,甚至没有一种以NodeList编程方式创建s 的方法(即创建一个空的并稍后添加节点),它们仅由一些DOM方法/属性返回.

  • 似乎方法"keys","entries"和"forEach"我出现在NodeList中,但在HTMLCollection中缺失 (6认同)
  • @user1032531:好吧,如果您对选定的 DOM 元素之一进行任何更改(例如添加一个子元素),那么您当然会看到更改,因为它是同一个 DOM 元素。但是,假设您选择了所有 `td` 元素,稍后添加新的 `td` 元素将不会自动更新选择以包含新元素。 (2认同)
  • @FelixKling:你应该提到并非所有[`NodeList`s](https://developer.mozilla.org/en-US/docs/DOM/NodeList)都是实时的. (2认同)
  • 我希望他们都是阵列 (2认同)
  • @KrzysztofGrzybek 没错,而且非常烦人。为什么他们中的一个有 `.forEach()` 而另一个没有? (2认同)

Dan*_*mms 29

0. a和a有什么区别?HTMLCollectionNodeList

以下是一些定义.

DOM Level 1 Spec - 其他对象定义:

接口HTMLCollection

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

DOM Level 3 Spec - NodeList

接口NodeList

NodeList接口提供有序节点集合的抽象,而不定义或约束此集合的实现方式.DOM中的NodeList对象是实时的.

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

因此,它们都可以包含实时数据,这意味着DOM将在其值发生时进行更新.它们还包含一组不同的功能.

如果您运行脚本,tableDOM元素包含a childNodes NodeList[2]和a,您将注意到是否检查控制台children HTMLCollection[1].他们为什么不同?因为HTMLCollection只能包含元素节点,所以NodeList还包含一个文本节点.

在此输入图像描述

1. document.getElementsByTagName("td")和之间有什么区别$("td")

document.getElementsByTagName("td")返回DOM元件的阵列(一NodeList),$("td")被称为jQuery对象,其具有从所述元件document.getElementsByTagName("td")上其属性0,1,2等,主要的区别是,jQuery对象是慢一点来检索,但可访问所有的方便jQuery函数.

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

他们对自己的属性的对象0,1,2等设置为DOM元素.这是一个简单的例子:它是如何工作的:

的jsfiddle

    var a = {
        1: "first",
        2: "second"
    }
    alert(a[1]);
Run Code Online (Sandbox Code Playgroud)

3.什么是难以捉摸的"NodeLists",我该如何选择?

您一直在代码中检索它们,getElementsByClassNamegetElementsByTagName返回NodeLists

节点列表


Shr*_*dha 10

HTMLCollection已经说了这么多,但认为一个更概括的答案版本并用一个例子来解释和之间的差异NodeList会有所帮助。

DOM 中的节点类型

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

在此输入图像描述

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

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

    • 如果该节点是元素节点,则该nodeType属性将返回1
    • 如果该节点是属性节点,则该nodeType属性将返回2
    • 如果节点是文本节点,该nodeType属性将返回3
    • 如果该节点是注释节点,该nodeType属性将返回8
    • 该属性是只读的。

HTMLCollection 与 NodeList

在此输入图像描述

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

<ul>
  <li>foo</li>
  <li>bar</li>
  <li>bar</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
// 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); 
Run Code Online (Sandbox Code Playgroud)


Sun*_*Sun 5

附加说明

HTMLCollection和NodeList有什么区别?

的HTMLCollection只包含元素节点(标签)和节点列表包含了所有的节点

有四种节点类型:

  1. 元素节点
  2. 属性节点
  3. 文字节点
  4. 评论节点

nodeTypes

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

考虑以下:

<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>
Run Code Online (Sandbox Code Playgroud)

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

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

HTMLCollection和NodeList之间的区别