1

I have some divs that each one of them contains multiple images inside. Every single image has the same class. At the end of the divs, I have a button that, when clicked, executes a Javascript function which loops through images successfully. But I need the for loop to be more precise. My code looks something like this.

My HTML div structure looks something like this.

        <div>
            <img class="myImage" src="image1.png">
            <img class="myImage" src="image2.png">
            <img class="myImage" src="image3.png">
            <button onclick="imageLooper()">Click here!</button>
        </div>
        <div>
            <img class="myImage" src="image4.png">
            <img class="myImage" src="image5.png">
            <img class="myImage" src="image6.png">
            <button onclick="imageLooper()">Click here!</button>
        </div>
            <img class="myImage" src="image7.png">
            <img class="myImage" src="image8.png">
            <img class="myImage" src="image9.png">
            <button onclick="imageLooper()">Click here!</button>
        </div>
        <script src="js/main.js"></script>

My javascript for loop is just a basic for loop.

    function imageLooper() {
    var images = document.getElementsByClassName("myImage");
    for (var i = 0; i < images.length; i++) {
        console.log(images[i]);
    }
}

It successfully loops through all of them. But the problem is that, I want to make this for loop to be more precise. I mean, the loop should not loop through all of the images, but it should loop through inside the div that the button is clicked. The problem is, these divs are dynamic. I mean, these divs printed(don't know if printed is the right term) from mysql with php code. I wrote a so called admin panel for this. So whenever I add something from admin panel, these divs increase by one, or whenever I delete from admin panel, one div is deleted.

In short. How can I loop through images. I cannot change classes because this divs are printed by PHP. Is it possible to do this by just in Javascript.

PS: I can change my PHP code so that every div can have distinct id.

Oguz
  • 13
  • 1
  • 5
  • Inside imageLooper() try this.parentNode.getElementsByClassName('myImage'). 'this' will refer to your button you clicked, thus the parentNode should contain your button and the images you would like to loop through. – WNP Mar 01 '21 at 22:21
  • Dupe really does not explain how to go from the child to the parent.... – epascarello Mar 01 '21 at 22:35

3 Answers3

0

Reference the button that is clicked, select the parent, select the children

function imageLooper(btn) {
  var images = btn.closest("div").getElementsByClassName("myImage");
  for (var i = 0; i < images.length; i++) {
    console.log(images[i]);
  }
}
<div>
  <img class="myImage" src="image1.png">
  <img class="myImage" src="image2.png">
  <img class="myImage" src="image3.png">
  <button onclick="imageLooper(this)">Click here!</button>
</div>
<div>
  <img class="myImage" src="image4.png">
  <img class="myImage" src="image5.png">
  <img class="myImage" src="image6.png">
  <button onclick="imageLooper(this)">Click here!</button>
</div>
<div>
  <img class="myImage" src="image7.png">
  <img class="myImage" src="image8.png">
  <img class="myImage" src="image9.png">
  <button onclick="imageLooper(this)">Click here!</button>
</div>
<script src="js/main.js"></script>

It would be a lot cleaner if you did not us inline events and used classes

document.querySelectorAll(".slideshow").forEach(function(div) {
  var btn = div.querySelector("button");
  var images = div.querySelectorAll("img");

  btn.addEventListener("click", function() {
     console.log(images);
  });
});
<div class="slideshow">
  <img class="myImage" src="image1.png">
  <img class="myImage" src="image2.png">
  <img class="myImage" src="image3.png">
  <button>Click here!</button>
</div>
<div class="slideshow">
  <img class="myImage" src="image4.png">
  <img class="myImage" src="image5.png">
  <img class="myImage" src="image6.png">
  <button>Click here!</button>
</div>
<div class="slideshow">
  <img class="myImage" src="image7.png">
  <img class="myImage" src="image8.png">
  <img class="myImage" src="image9.png">
  <button>Click here!</button>
</div>
epascarello
  • 204,599
  • 20
  • 195
  • 236
0

Instead of:

var images = document.getElementsByClassName("myImage");

Add a parameter to your elements and pass itself in. For example:

<button onclick="imageLooper(this)">Click here!</button>

Note: 'this'. Then define imageLooper as:

function imageLooper(me) {
    var images = me.parentNode.getElementsByClassName("myImage");
}

Now, images contains only the images in the current block.

0

In this day and age using inline event handlers is not ideal - you can easily externalise this and use a single event listener using querySelectorAll to identify nodes of interest.

    document.querySelectorAll('div button').forEach( bttn=>{
        bttn.addEventListener('click',e=>{
            let col=e.target.parentNode.querySelectorAll('img');
                col.forEach( img=>{
                    console.log( img )
                })
        })
    })
<div>
  <img class="myImage" src="image1.png">
  <img class="myImage" src="image2.png">
  <img class="myImage" src="image3.png">
  <button>Click here!</button>
</div>
<div>
  <img class="myImage" src="image4.png">
  <img class="myImage" src="image5.png">
  <img class="myImage" src="image6.png">
  <button>Click here!</button>
</div>
<div>
  <img class="myImage" src="image7.png">
  <img class="myImage" src="image8.png">
  <img class="myImage" src="image9.png">
  <button>Click here!</button>
</div>
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46