JavaScript DOM Collections

The Document Object Model (DOM) collections in JavaScript provide a way to manage and manipulate groups of related nodes efficiently.

These collections include NodeList, HTMLCollectionand NamedNodeMap.

Understanding how to work with these collections is crucial for performing batch operations on elements, enhancing performance, and building dynamic, interactive web applications.

Let's not west time and start explaining how it works with example.

NodeList

A NodeListis a collection of nodes that can be returned by methods like querySelectorAll(), childNodes, and getElementsByTagName().

It can be either live (automatically updated when the document changes) or static (a snapshot at the time of collection).

// Using querySelectorAll to get a NodeList
const items = document.querySelectorAll(".item");
items.forEach((item) => console.log(item));

// Accessing child nodes as a NodeList
const parent = document.getElementById("parent");
const children = parent.childNodes;
children.forEach((child) => console.log(child));

Example

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Title of the Document</title>
  </head>
  <body>
    <h1 id="heading">Welcome to CodingKoleji</h1>
    <div class="parent">
      <p >This is first Paragraphs</p>
      <p >This is second Paragraphs</p>
      <p >This is third Paragraphs</p>
    </div>
    <ul class="list-item">
      <li class="item">Banana</li>
      <li class="item">Apple</li>
      <li class="item">Orange</li>
    </ul>
  <script>
      const items = document.querySelectorAll(".item");
      items.forEach((item) => console.log(item));
      
      // Accessing child nodes as a NodeList
      const parent = document.getElementById("parent");
      const children = parent.childNodes;
      children.forEach((child) => console.log(child));
    </script>
  </body>
</html>

HTMLCollection

An HTMLCollectionis a collection of element nodes, usually returned by methods like getElementsByClassName(), getElementsByTagName(), and children.

HTMLCollection is always live, meaning it reflects the current state of the document.

// Using getElementsByClassName to get an HTMLCollection
const buttons = document.getElementsByClassName("btn");
Array.from(buttons).forEach((button) => console.log(button));

// Accessing element children as an HTMLCollection
const container = document.getElementById("container");
const childElements = container.children;
Array.from(childElements).forEach((child) => console.log(child));

Example

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Title of the Document</title>
  </head>
  <body>
    <h1 id="heading">Welcome to CodingKoleji</h1>
    <div id="container">
      <p >This is first Paragraphs</p>
      <p >This is second Paragraphs</p>
      <p >This is third Paragraphs</p>
    </div>
      <button class="btn login">Login</button>
      <button class="btn register">Register</button>
  <script>
    // Using getElementsByClassName to get an HTMLCollection
    const buttons = document.getElementsByClassName("btn");
    Array.from(buttons).forEach((button) => console.log(button));
    
    // Accessing element children as an HTMLCollection
    const container = document.getElementById("container");
    const childElements = container.children;
    Array.from(childElements).forEach((child) => console.log(child));
  </script>
  </body>
</html>

Converting Collections to Arrays

DOM collections like NodeListand HTMLCollectionare not true arrays but can be converted to arrays for easier manipulation with array methods. getElementsByClassName().

This can be done using Array.from()or the spread operator (...).

// Converting a NodeList to an array
const nodeList = document.getElementById("item");
const nodeArray = Array.from(nodeList);
nodeArray.forEach((node) => console.log(node));

// Converting an HTMLCollection to an array
const htmlCollection = document.getElementsByClassName("btn");
const btnArray = [...htmlCollection];
btnArray.forEach((btn) => console/log(btn));

Example

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Title of the Document</title>
  </head>
  <body>
    <h1 id="heading">Welcome to CodingKoleji</h1>
    <ul class="list-item">
      <li class="item">Banana</li>
      <li class="item">Apple</li>
      <li class="item">Orange</li>
    </ul>
    <button class="btn login">Login</button>
    <button class="btn register">Register</button>
  <script>
    // Converting a NodeList to an array
    const nodeList = document.getElementsByClassName("item");
    const nodeArray = Array.from(nodeList);
    nodeArray.forEach((node) => console.log(node));
    
    // Converting an HTMLCollection to an array
    const htmlCollection = document.getElementsByClassName("btn");
    const btnArray = [...htmlCollection];
    btnArray.forEach((btn) => console.log(btn));
  </script>
  </body>
</html>

Iterating Over Collections

DOM collections can be iterated using loops, forEach(), or converting them to arrays for advanced array methods like map(), filter()and reduce().

// Iterating over a NodeList
const items = document.querySelectorAll(".item");
items.forEach((item) => console.log(item));

// Iterating over an HTMLCollection
const buttons = document.getElementsByClassName("btn");
Array.from(buttons).forEach((button) => console.log(button));

// Using advanced array methods after conversion
const nodeArray = Array.from(document.querySelectorAll(".item"));
const itemTexts = nodeArray.map(node => node.textContent);
console.log(itemTexts);

Example

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Title of the Document</title>
  </head>
  <body>
    <h1 id="heading">Welcome to CodingKoleji</h1>
    <ul class="list-item">
      <li class="item">Banana</li>
      <li class="item">Apple</li>
      <li class="item">Orange</li>
    </ul>
    <button class="btn login">Login</button>
    <button class="btn register">Register</button>
  <script>
    // Iterating over a NodeList
    const items = document.querySelectorAll(".item");
    items.forEach((item) => console.log(item));
    
    // Iterating over an HTMLCollection
    const buttons = document.getElementsByClassName("btn");
    Array.from(buttons).forEach((button) => console.log(button));
    
    // Using advanced array methods after conversion
    const nodeArray = Array.from(document.querySelectorAll(".item"));
    const itemTexts = nodeArray.map(node => node.textContent);
    console.log(itemTexts);
  </script>
  </body>
</html>

Live vs. Static Collections

Understanding the difference between live and static collections is important for efficient DOM manipulation.

Live collections automatically update to reflect changes in the DOM, whereas static collections remain unchanged after their creation.

// Demonstrating live collection
const liveCollection = document.getElementsByTagName("p");
console.log(liveCollection.length); // Outputs the number of <p> elements

const newParagraph = document.createElement("p");
document.body.appendChild(newParagraph);
console.log(liveCollection.length); // Outputs the updated number of <p> elements

// Demonstrating static collection
const staticCollection = document.querySelectorAll("p");
console.log(liveCollection.length); // Outputs the number of <p> elements

document.body.appendChild(newParagraph);
console.log(staticCollection.length); // Outputs the original number of <p> elements

Example

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Title of the Document</title>
  </head>
  <body>
    <h1 id="heading">Welcome to CodingKoleji</h1>
    <div id="container">
      <p >This is first Paragraphs</p>
      <p >This is second Paragraphs</p>
      <p >This is third Paragraphs</p>
    </div>
  <script>
    // Demonstrating live collection
    const liveCollection = document.getElementsByTagName("p");
    console.log(liveCollection.length); // Outputs the number of <p> elements
    
    const newParagraph = document.createElement("p");
    document.body.appendChild(newParagraph);
    console.log(liveCollection.length); // Outputs the updated number of <p> elements
    
    // Demonstrating static collection
    const staticCollection = document.querySelectorAll("p");
    console.log(liveCollection.length); // Outputs the number of <p> elements
    
    document.body.appendChild(newParagraph);
    console.log(staticCollection.length); // Outputs the original number of <p> elements
  </script>
  </body>
</html>

Manipulating Multiple Elements

Using DOM collections allows for efficient batch operations on multiple elements.

This can include applying styles, setting attributes, or adding event listeners.

// Applying styles to all elements in a collection
const items = document.querySelectorAll(".item");
items.forEach(item => item.style.color = "blue" );

// Setting attributes for all elements in a collection
const images = document.getElementsByTagName("img");
Array.from(images).forEach(img => img.setAttribute("alt", "Image description"));

// Adding event listeners to all elements in a collection
const buttons = document.getElementsByClassName("btn");
Array.from(buttons).forEach(btn => btn.addEventListener("click", () => alert("Button clicked!")));

Example

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Title of the Document</title>
  </head>
  <body>
    <h1 id="heading">Welcome to CodingKoleji</h1>
    <ul class="list-item">
      <li class="item">Banana</li>
      <li class="item">Apple</li>
      <li class="item">Orange</li>
    </ul>
    <img src="../../images/random-images/dog.jpg"/>

    <button class="btn login">Login</button>
    <button class="btn register">Register</button>
  <script>
    // Applying styles to all elements in a collection
    const items = document.querySelectorAll(".item");
    items.forEach(item => item.style.color = "blue" );
    
    // Setting attributes for all elements in a collection
    const images = document.getElementsByTagName("img");
    Array.from(images).forEach(img => img.setAttribute("alt", "Image description"));
    
    // Adding event listeners to all elements in a collection
    const buttons = document.getElementsByClassName("btn");
    Array.from(buttons).forEach(btn => btn.addEventListener("click", () => alert("Button clicked!")));
  </script>
  </body>
</html>

DOM collections in JavaScript, including NodeList, HTMLCollection, and NamedNodeMap, are essential tools for managing groups of related nodes.

Let's learn about DOM NodeList in the next chapter.