NodeLists and HTMLCollections have different properties availables. It is important as a developer to understand how to get one or the other in order to work in the most efficient way.
Get a single item
To get a HTMLElement, we can use the following methods:
querySelector
getElementById
To check by yourself, run the following script and check your browser console:
const querySelector = document.querySelector('li');
console.log('Using `querySelector`:', querySelector.constructor.name, querySelector , querySelector.attributes);
const getElementById = document.getElementById('ul');
console.log('Using `getElementById`:', getElementById.constructor.name, getElementById, getElementById.attributes);
Get several items
To get static NodeList, we can use this method:
querySelectorAll
const querySelectorAll = document.querySelectorAll('li');
console.log('Using `querySelectorAll`:', querySelectorAll);
To get a HTMLCollection, we can use these methods:
getElementsByName
getElementsByClassName
getElementsByTagName
const getElementsByName = document.getElementsByName('li');
console.log('Using `getElementsByName`:', getElementsByName);
const getElementsByClassName = document.getElementsByClassName('li');
console.log('Using `getElementsByClassName`:', getElementsByClassName);
const getElementsByTagName = document.getElementsByTagName('li');
console.log('Using `getElementsByTagName`:', getElementsByTagName);
childNodes
vs. children
properties
childNodes
and children
properties can be called on a HTMLElement.
- Accessing the
childNodes
property on a HTMLElement returns a NodeList. Whitespace between elements are also text nodes (we can filter them with the[…nodeList].filter(…)
syntax (see code below).
const children = document.getElementById('ul').children;
console.log('NodeList', children);
console.log('Filtered NodeList', [...children].filter(node => node.nodeName == 'LI'));
- Accessing the
children
property on a HTMLElement returns a HTMLCollection.
const childNodes = document.getElementById('ul').childNodes;
console.log('Using `childNodes` property:', childNodes);
Get a live NodeList
As seen above, querySelectorAll
returns a static NodeList. To get a live NodeList, we need to get the parent HTMLElement of the nodes and access its childNodes
property.
const liveNodeList = document.getElementsByTagName('ul').childNodes;
console.log(liveNodeList);
Lets compare the behaviour of a static NodeList and a live one . Run the code below and check your browser's console:
const ul = document.getElementsByTagName('ul')
// Get a static NodeList using `querySelectorAll`
const staticNodeList = document.querySelectorAll('li');
// Add a LI element
const newLi = document.createElement('li');
newLi.innerText = 'item4';
ul.appendChild(newLi);
console.log('Added element:', newLi.constructor.name, newLi);
// Result
console.log('staticNodeList after:', [...staticNodeList]); // The new LI was not added
console.log('liveNodeList after:', [...liveNodeList].filter(node => node.nodeName == 'LI')); // The new LI was added