A NodeList is similar to an array with few important differences

A NodeList is similar to an array with few important differences

Technically speaking, if you know how to get around arrays, then you already know how to get around NodeLists, too.

This is because, at the end of the day, both arrays and NodeLists represent a list of data.

An array represents a collection of non-HTML data, while a NodeList represents a collection of HTML elements.

A NodeList is a separate object designed to interact specifically with HTML elements.

But apart from that, just like an array:

1) A NodeList is a type of specialised object, too. So, it has access to methods and properties such as the length property.

2) The index of individual HTML items inside the NodeList starts with a zero, too.

3) You can use a "for" loop statement to iterate over each HTML element inside the NodeList and do something with it:

//Step 1: Create a NodeList by selecting a bunch of HTML elements
const faqs = document.querySelectorAll(".faqs");

//Step 2: Loop over the NodeList
for(let i = 0; i < faqs.length; i++){
  
  // Add event listener to each HTML element
  faqs[i].addEventListener("click", function(){
    //Open FAQ content
  });
  
}

Having said that, remember that a NodeList is not a true array.

So, it doesn't support the core methods of an array.

For example, you can't access the core array methods, such as:

  1. push()pop(): Modify the contents of the list.
  2. shift()unshift(): Add or remove items from the beginning.
  3. map()filter()reduce(): Powerful transformation and iteration methods.
  4. sort()reverse(): Change the order of elements.

Most importantly, you can't access the forEach() method on a NodeList

The forEach() method only works on arrays because it is native to arrays.

But all hope is not lost.

These days, many modern browsers support forEach() directly on a NodeList for convenience, even though it's not part of the official Web API specification:

//Step 1: Select all FAQ headers
const faqHeaders = document.querySelectorAll(".faqs .faq-header");

//Step 2: Loop through all selected FAQ headers

faqHeaders.forEach(function(faqHeader){
  faqHeader.addEventListener("click", function () {
     faqHeader.parentElement.classList.toggle("is-open");
   });
});

The above code works just fine. So, you can just use forEach directly on NodeList in these browsers without issues.

But, If you need to support older browsers that don't have a native forEach implementation for NodeList, you must use a polyfill to add this functionality.

💡
In JavaScript, a polyfill is a piece of code that provides modern functionality on older browsers that don't support it natively.

It basically fills the gap in functionality by implementing the missing feature in a way that works on older browsers.

A popular polyfill is the core-js library, which provides polyfills for various ES6 features:

GitHub - zloirock/core-js: Standard Library
Standard Library. Contribute to zloirock/core-js development by creating an account on GitHub.

If you don't want to use an external library...

You can convert a NodeList into an array and get access to all the Array methods.

For example, if you want to use the forEach() method on a NodeList, you have to convert the NodeList into an array and then use it:

//Step 1: Create a NodeList by selecting a bunch of HTML elements
const faqs = document.querySelectorAll(".faqs");

//Step 2: Convert the NodeList created into an array
const faqsArray = Array.from(faqs);

//Step 3: Then use the forEach method
faqsArray.forEach(function(faq){
  faq.addEventListener("click", function(){
    //Open FAQ content
  });
});

The same process applies to using other array methods on NodeLists, too.

There are many use cases for why you might want to convert a NodeList into an array.

For example:

  1. If you want to sort HTML elements by changing their original order, then you have to convert the NodeList into an array and then sort the HTML elements in any way you want.
  2. If you're creating an "Add to Cart" functionality, then you have to delete HTML elements from the cart or add them back. This becomes possible only if you convert a NodeList into an array.

We could see this in practice in a future lesson.

For now, I just want you to remember that you can convert a NodeList into an array very easily.

Now that you understand NodeLists and their limitations clearly, starting from the next lesson, we will work on some interesting projects one by one.