javascriptarraysfunctionfor-loopvariable-assignment

Can you assign an element's class list to a variable by clicking on the element?


The main question I have is: Is there a way to assign to a variable an element's class list by clicking on said element without directly referencing the element in the JavaScript.

Expanding on this, I'm trying to create a function that - on clicking an image in a photo grid - expands the image making it clearer for people to see. I made a for loop that loops through an array that contains the class lists of all images in the grid, the idea was that upon clicking on any one of the images a function that contains the loop would be called and the class list for the image that was clicked would be stored as a variable, the loop would then compare each value in the array to the variable and upon a match would apply a class that enlarges that particular image, this way I could use one function for every image in the grid instead of writing 15+ functions where each one was called depending on the image clicked. I've run into an issue when trying to retrieve the class list for the image that was clicked on - that being I can't figure out how to retrieve the class list for an element by clicking on said element without referencing it. What I mean by this is that I'm not trying to use querySelector() or getElementById()/ClassName() to directly reference the element (in this case photo) as I'd have to write 15+ different functions all corresponding to a specific element (photo). Instead I'm trying to pull the classList for any one element in a group of elements with only one function

As I said I could just make 15+ different functions each with a variable directly assigning that specific images class but that hardly seems like the best way to do this. If this just isn't possible also let me know please.

My JS as it stands:

document.addEventListener("DOMContentLoaded", function() {
    
    document.querySelector(".photo-grid").addEventListener("click", e => {
        let figureArray = [] = e.currentTarget.children
        for (let i = 0; i < figureArray.length; i++ ) {
            if (figureArray[i].classList.contains("picture")) {
                console.log(figureArray[i].classList.value);
            }
        }
    });
});

HTML:

<section class="photo-grid">
    <figure class="picture 1 square-image"><img src="tempSource" alt="Covered Gothic Bookcase"></figure>
    <figure class="picture 2 tall-image"><img src="tempSource" alt="Built-in Bookcase & Staircase"></figure>
    <figure class="picture 3 square-image"><img src="tempSource" alt="Extending Coffee Table"></figure>
    <figure class="picture 4 tall-image"><img src="tempSource" alt="Mahogany Fire Guard"></figure>
    <figure class="picture 5 tall-image"><img src="tempSource" alt="Bespoke Ash Staircase"></figure>
    <figure class="picture 6 tall-image"><img src="tempSource" alt="Replica Door"></figure>
    <figure class="picture 7 square-image"><img src="tempSource" alt="Drawer Unit"></figure>
    <figure class="picture 8 tall-image"><img src="tempSource" alt="Casement Windows"></figure>
    <figure class="picture 9 square-image"><img src="tempSource" alt="Staircase"></figure>
    <figure class="picture 10 square-image"><img src="tempSource" alt="Ash Dressing Table"></figure>
    <figure class="picture 11 tall-image"><img src="tempSource" alt="Bespoke Staircase"></figure>
    <figure class="picture 12 tall-image"><img src="tempSource" alt="Country-Style Kitchen"></figure>
    <figure class="picture 13 tall-image"><img src="tempSource" alt="Hand-Cut Dovetails"></figure>
    <figure class="picture 14 square-image"><img src="tempSource" alt="Solid Oak Memorial Bench"></figure>
    <figure class="picture 15 square-image"><img src="tempSource" alt="Bespoke Built-in Cupboards"></figure>
</section>

Solution

  • You can attach an event listener to each photo, or use event delegation like I have here, attaching the listener to the container element, and checking to see if the clicked item is the desired element. Write a callback function that looks at the event passed to it to determine which element was clicked and log its classList.

    Edit: I've modified my example html to match yours. You seem to be struggling with the nested elements: <figure><img></figure>. The clicks are happening on the images, which don't have the "picture" className. I believe you want the className for the figure, even if you clicked on the figure's img child. We're using event delegation here, so using e.currentTarget returns the specific element that we added our event listener to. By looking for the <figure> that is nearest the e.target, we can retrieve the relevant figure tag.

     document.querySelector(".photo-grid").addEventListener(
      "click",
      e => {
        const theFigure = e.target.closest("figure");
        if (theFigure.classList.contains("picture")) {
          console.log(theFigure.classList.value)
        }
      }
     );
    <section class="photo-grid">
        <figure class="picture 1 square-image"><img src="tempSource" alt="Covered Gothic Bookcase"></figure>
        <figure class="picture 2 tall-image"><img src="tempSource" alt="Built-in Bookcase & Staircase"></figure>
        <figure class="picture 3 square-image"><img src="tempSource" alt="Extending Coffee Table"></figure>
        <figure class="picture 4 tall-image"><img src="tempSource" alt="Mahogany Fire Guard"></figure>
        <figure class="picture 5 tall-image"><img src="tempSource" alt="Bespoke Ash Staircase"></figure>
        <figure class="picture 6 tall-image"><img src="tempSource" alt="Replica Door"></figure>
        <figure class="picture 7 square-image"><img src="tempSource" alt="Drawer Unit"></figure>
        <figure class="picture 8 tall-image"><img src="tempSource" alt="Casement Windows"></figure>
        <figure class="picture 9 square-image"><img src="tempSource" alt="Staircase"></figure>
        <figure class="picture 10 square-image"><img src="tempSource" alt="Ash Dressing Table"></figure>
        <figure class="picture 11 tall-image"><img src="tempSource" alt="Bespoke Staircase"></figure>
        <figure class="picture 12 tall-image"><img src="tempSource" alt="Country-Style Kitchen"></figure>
        <figure class="picture 13 tall-image"><img src="tempSource" alt="Hand-Cut Dovetails"></figure>
        <figure class="picture 14 square-image"><img src="tempSource" alt="Solid Oak Memorial Bench"></figure>
        <figure class="picture 15 square-image"><img src="tempSource" alt="Bespoke Built-in Cupboards"></figure>
    </section>