arrow cursor
< javascript tutorials

Calling JavaScript On Multiple DIV Elements Without ID Attribute | Tweet It | CSS Visual Dictionary

Written by @js_tut (Twitter)

In this tutorial we'll take a look on how to call JavaScript code on multiple DIV elements on the page, when they are missing the id attribute (or when calling an individual element is not permitted, for some reason.)

Let's say you have a few arbitrary HTML DIV elements:

<div class = "image">content 1</div>
<div class = "image">content 2</div>
<div class = "image">content 3</div>

You can select these DIV elements, even though they don't have id attributes. In fact, they share the same class name "image". Let's see a few alternatives we have when it comes to selecting a collection of HTML elements. There are at least three ways of doing this in JavaScript.

1. Using document.getElementsByClassName

In order to select the elements in question, you can use document.getElementsByClassName function. It returns a non-iterable collection of all elements. Which is basically is just a list of elements, similar (but not exactly) an Array.

let divs = document.getElementsByClassName("image");

2. Using document.getElementsByTagName

Same thing here, only using a different JavaScript function.

let divs = document.getElementsByTagName("div");

3. Using document.querySelectorAll

You can do the same exact thing with document.querySelectorAll function.

let divs = document.querySelectorAll("div");

All 3 functions: getElementsByClassName, getElementsByTagName and querySelector return exactly the same list of selected objects. It's just querySelectorAll function returns a NodeList, and others return HTMLCollection.

console.log(divs);

The getElementByClassName and getElementsByTagName functions will return a HTMLCollection:

HTMLCollection(3) [div.image, div.image, div.image]
0         : div.image
1         : div.image
2         : div.image
length    : 3, __proto__ : HTMLCollection

Whereas, the querySelectorAll function will return a NodeList. But they are both iterable and can be used for the same end result we'll see in a moment.

NodeList(3) [div.image, div.image, div.image]
0         : div.image
1         : div.image
2         : div.image
length    : 3, __proto__ : NodeList

In both cases exactly 3 <div> objects were returned, just as expected.

You can now either pass the divs object to Object.entries method, or call forEach method of the returned Array-like object (Both HTMLCollection and NodeList have a length property on it.)

But before we do that... let's simply attach an event listener to each individual object.

Let's attach addEventListener method to each DIV in the collection:

/* Add event listeners to both elements */
divs[0].addEventListener("click", function() {
    console.log("Hello " + this + " (" + this.innerHTML + ") from event listener [0]");
    /* Here, "this" refers to 1st div */
});

divs[1].addEventListener("click", function() {
    console.log("Hello " + this + " (" + this.innerHTML + ") from event listener [1]");
    /* Here, "this" refers to 2nd div */
});

divs[2].addEventListener("click", function() {
    console.log("Hello " + this + " (" + this.innerHTML + ") from event listener [2]");
    /* Here, "this" refers to 3rd div */
});

Now whenever you click on any of the DIVs, you will have its object and innerHTML printed to the console.

In some cases you will want to do this individually. But in most cases, you will probably want to reduce the size of your code. One way of doing that is to use the map method.

But map method works only on Arrays. It will not work on an HTMLCollection.

No problem. You can convert our collection to an array using Object.entries method.

First, convert your HTMLCollection using Object.entries(collection). Then, since it's an iterable at this point, you can now use the .map method on it.

Using Array.map method with Object.entries(elements)

/* Walk through the entire set of items in a HTMLCollection
   by first converting it to an Array using Object.entries method function */
Object.entries(divs).map(( object ) => {
    // Here, object = Array[index, object] (object is the HTML element object)
    // This means that the actual element is stored in object[1] not object
    // Do whatever you need to do with it here. In this case we attach a click event:
    object[1].addEventListener("click", function() {
        // Output innerHTML of the clicked element
        console.log("Hello " + this + " (" + this.innerHTML + ") from map method...");
    });
});

Within loop object[0] will refer to the index of current item in HTMLCollection.

And object[1] will actually point to the JavaScript object of that element.

You can do whatever you want with it. Attach mouse hover/blur events. Check their attributes. Remove them. Or any other thing that you would normally do to JavaScript objects, depending on your case.

Summary

We can use three JavaScript methods to select a list of ID-less elements. And then we can work with them by passing the divs either to Object.entries method or to Array.forEach method:

let divs = document.getElementsByClassName("image");
let divs = document.getElementsByTagName("div");
let divs = document.querySelectorAll("div");

// Using Object.entries method
Object.entries(divs).map(( object ) => { console.log( object ); });

// Using Array.forEach method
divs.forEach(function( object ) { console.log( object ); });

Note, this tutorial was not meant to say which method is "better". But to explain available options.

That's pretty much all there is to it. Hope it helps!

How To Create an Interactive Flex Layout Designer In JavaScript | Tweet It | CSS Visual Dictionary