I've always been confused between HTMLCollections, objects, and arrays when it comes to DOM. For instance...
- What is the difference between
document.getElementsByTagName("td")
and$("td")
? $("#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?- What is the elusive "NodeLists" all about, and how do I select one?
Please also provide any interpretation of the below script.
Thank you
[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>
Additional note
What is the difference between a HTMLCollection and a NodeList?
A HTMLCollection contains only element nodes (tags) and a NodeList contains all nodes.
There are four node types:
nodeTypes
Whitespace inside elements is considered as text, and text is considered as nodes.
Consider the following:
Whitespace:
<ul id="myList"> <li>List item</li></ul>
No whitespace:
<ul id="myList"><li>List item</li></ul>
$("td")
is extended jQuery object and it has jQuery methods, it returns jquery object that contains array of html objects.document.getElementsByTagName("td")
is raw js method and returns NodeList. See this articleThe NodeList objects are collections of Node's, returned for example by x.childNodes property or document.querySelectorAll() method. In some cases, the NodeList is live, which means that changes in the DOM automatically update the collection! For example, Node.childNodes is live:
But in some other cases, the NodeList is static, where any changes in the DOM does not affect the content of the collection. querySelectorAll() returns a static 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 children or methods like as document.getElementsByTagName(), and could only have HTMLElement's as their items.
HTMLCollection also exposes its members directly as properties by both name and index:
The HTMLElement is just one type of Nodes:
The Node can be several types. Most important ones are as following:
<p>
or<div>
.So, a big difference is that HTMLCollection contains only HTMLElements but NodeList also contains the comments, white-space texts (carriage return chars, spaces..), etc. Check it as in following snippet:
Both HTMLCollection and NodeList contain the length property you can use to loop over their items. Don't use for...in or for each...in to enumerate the items in NodeLists, since they will also enumerate its length and item properties and cause errors if your script assumes it only has to deal with element objects. Also, for..in is not guaranteed to visit the properties in any particular order.
0. What is the difference between an
HTMLCollection
and aNodeList
?Here are some definitions for you.
DOM Level 1 Spec - Miscellaneous Object Definitions:
DOM Level 3 Spec - NodeList
So they can both contain live data which means that the DOM will update when their values do. They also contain a different set of functions.
You will note if you inspect the console if you run your scripts that the
table
DOM element contains both achildNodes
NodeList[2]
and achildren
HTMLCollection[1]
. Why are they different? BecauseHTMLCollection
can only contain element nodes, NodeList also contains a text node.1. What is the difference between
document.getElementsByTagName("td")
and$("td")
?document.getElementsByTagName("td")
returns an array of DOM elements (aNodeList
),$("td")
is called a jQuery object which has the the elements fromdocument.getElementsByTagName("td")
on its properties0
,1
,2
, etc. The main difference is that the jQuery object is a little slower to retrieve but gives access to all the handy jQuery functions.2.
$("#myTable")
and$("td")
are objects (jQuery
objects). Why isconsole.log
also showing the array of DOM elements beside them, and are they not objects and not an array?They are objects with their properties
0
,1
,2
, etc. set to the DOM elements. Here's a simple example: of how it works:jsFiddle
3. What is the elusive "NodeLists" all about, and how do I select one?
You have been retrieving them in your code,
getElementsByClassName
andgetElementsByTagName
both returnNodeList
sFirst I will explain the difference between
NodeList
andHTMLCollection
.Both interfaces are collections of DOM nodes. They differ in the methods they provide and in the type of nodes they can contain. While a
NodeList
can contain any node type, anHTMLCollection
is supposed to only contain Element nodes.An
HTMLCollection
provides the same methods as aNodeList
and additionally a method callednamedItem
.Collections are always used when access has to be provided to multiple nodes, e.g. most selector methods (such as
getElementsByTagName
) return multiple nodes or getting a reference to all children (element.childNodes
).For more information, have a look at DOM4 specification - Collections.
getElementsByTagName
is method of the DOM interface. It accepts a tag name as input and returns aHTMLCollection
(see DOM4 specification).$("td")
is presumably jQuery. It accepts any valid CSS/jQuery selector and returns a jQuery object.The biggest differences between standard DOM collections and jQuery selections is that DOM collections are typically live (not all methods return a live collection though), i.e. any changes to the DOM are reflected in the collections if they are affected. They are like a view on the DOM tree, whereas jQuery selections are snapshots of the DOM tree in the moment the function was called.
jQuery objects are array-like 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[ ... , ... , ... ]
.See the first part of my answer. You cannot select
NodeList
s, they are the result of a selection.As far as I know there is not even a way to create
NodeList
s programatically (i.e. creating an empty one and adding nodes later on), they are only returned by some DOM methods/properties.