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

时间:2013-04-02 11:50:13

标签: javascript jquery dom

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

  1. document.getElementsByTagName("td")$("td")之间的区别是什么?
  2. $("#myTable")$("td")是对象(jQuery对象)。为什么console.log还会在它们旁边显示DOM元素数组,它们不是对象而不是数组?
  3. 什么是难以捉摸的“NodeLists”,我该如何选择?
  4. 请同时提供以下脚本的任何解释。

    谢谢

    [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>
    

6 个答案:

答案 0 :(得分:96)

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

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

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

有关详细信息,请查看DOM4 specification - Collections

  

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

getElementsByTagName是DOM接口的方法。它接受标记名称作为输入并返回HTMLCollection(请参阅DOM4 specification)。

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

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

  

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

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

  

什么是难以捉摸的“NodeLists”,我该如何选择?

请参阅我的答案的第一部分。您无法选择 NodeList,它们是选择的结果

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

答案 1 :(得分:27)

0。 HTMLCollectionNodeList之间的区别是什么?

以下是您的一些定义。

DOM Level 1 Spec - Miscellaneous Object Definitions

  

界面HTMLCollection

     

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

DOM Level 3 Spec - NodeList

  

接口NodeList

     

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

     

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

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

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

enter image description here

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

document.getElementsByTagName("td")返回一个DOM元素数组(NodeList),$("td")称为jQuery对象,其document.getElementsByTagName("td")元素的属性为0 }},12等。主要区别在于jQuery对象的检索速度稍慢,但可以访问所有方便的jQuery函数。

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

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

jsFiddle

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

3。什么是难以捉摸的“NodeLists”,我如何选择一个?

您一直在代码中检索它们,getElementsByClassNamegetElementsByTagName都返回NodeList s

NodeList

答案 2 :(得分:3)

附加说明

HTMLCollection和NodeList有什么区别?

HTMLCollection 仅包含元素节点(标记), NodeList 包含所有节点

有四种节点类型:

  1. 元素节点
  2. 属性节点
  3. 文字节点
  4. 评论节点
  5. 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>
    

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

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

    Difference between HTMLCollection and a NodeList

答案 3 :(得分:2)

$("td")是扩展的jQuery对象,它有jQuery方法,它返回包含html对象数组的jquery对象。 document.getElementsByTagName("td")是原始js方法并返回NodeList。 See this article

答案 4 :(得分:0)

NodeList对象是Node的集合,例如通过x。childNodes属性或document.querySelectorAll()方法返回。在某些情况下,NodeList是活动的,这意味着DOM中的更改会自动更新集合!例如,Node.childNodes处于活动状态:

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。

HTMLCollection 是元素的实时且有序的集合(更改基础文档后会自动更新)。它可以是诸如children之类的属性或诸如document.getElementsByTagName()之类的方法的结果,并且只能将HTMLElement's 作为其项。

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

节点可以是several types。最重要的是:

  • 元素(1):元素节点,例如<p><div>
  • 属性(2):元素的属性。元素属性不再实现DOM4规范中的Node接口!
  • text(3):元素或属性的实际文本。
  • 评论(8):一个评论节点。
  • document(9):一个文档节点。

因此,一个很大的不同是HTMLCollection仅包含HTMLElements,而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都包含 length 属性,可用于循环它们的项目。不要使用... in或for每个... in来枚举NodeLists中的项目,因为它们还会枚举其长度和项目属性,并且如果您的脚本假定它只需要处理元素对象,则会导致错误。另外,不能保证for..in会以任何特定顺序访问属性。

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

答案 5 :(得分:0)

已经讲了很多,但是认为答案更概括,并举例说明HTMLCollectionNodeList之间的区别会有所帮助。

DOM中节点的类型

  • 有12种不同的节点类型,其中可能包含各种节点类型的子节点:

enter image description here

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

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

    • 如果该节点是元素节点,则nodeType属性将返回 1
    • 如果该节点是属性节点,则nodeType属性将返回 2
    • 如果该节点是文本节点,则nodeType属性将返回 3
    • 如果该节点是注释节点,则nodeType属性将返回 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);