1

I have a group of images in my HTML with the ID's "Hole#" ex: "Hole1", "Hole2" ... "HoleN". These IMG tags are loading a locally stored image. My goal is to print an alert when one of the images is clicked.

I found another StackOverflow question that I thought would answer my question. I've incorporated it into my code below. Unfortunately it did not achieve the desired effect.

//Dynamically creates images
for (let i = 1; i <= NUM_HOLES; i++) {
    let HoleID = `"hole${i}"`;
    let HoleIDPic = `"holePic${i}"`;
    holesString +=
    `<div id=`+ HoleID + `>
    <img id=` + HoleIDPic + ` src="" />
    </div>`
}

window.onload = function() {
      document.getElementById("img[id|=hole]").onclick = function()
      {
         alert("Clicked");
      };
   };

HTML:

   <section id="holes">

   </section>

replacing the code "img[id|=hole]" with "hole1" does work however (for hole1), So I've concluded its my syntax the ID selection.

Chris
  • 25
  • 7

2 Answers2

1

The whole idea of using similar ids on all images is the wrong approach.

Use a common CSS class instead. Then, to find out which image was clicked, use a single delegate listener and make use of the event object that is automatically passed to your click handler. I'm showing you an example with buttons instead of images:

const buttonDiv = document.querySelector('.buttons');

// lets add some buttons
for (let i = 0; i < 5; i++) {
  let button = document.createElement('button');
  button.type = 'button';
  button.className = 'button';
  button.textContent = 'Button Number ' + i;
  buttonDiv.appendChild(button);
}

// now let's add a delegate click listener on the div containing the buttons
buttonDiv.addEventListener('click', function(event) {
  // in any event listener, the event object has a `target` property, telling you which element the event was raised on
  // this allows us to only react in the click listener if the clicked element meets certain conditions
  if (event.target.matches('button.button')) 
    console.log('you clicked on ' + event.target.textContent);
})
.buttons {
  background-color: #f0f0f0;
  padding: 10px;
}
<div class="buttons"></div>
connexo
  • 53,704
  • 14
  • 91
  • 128
  • This is a great to solve this problem, very elegant. I my problem was also solved by another person above, but I appreciate the help! In the future I'll be sure to use this method alternatively as It looks cleaner than my current method. – Chris Apr 17 '20 at 15:16
0

Try this

    
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <section id="holes"></section>

    <script>    
      loadImages(2);
      
      function loadImages(NUM_HOLES){
        
        const sectionHoles = document.getElementById('holes');

        //Dynamically creates images
        for (let i = 1; i <= NUM_HOLES; i++) {

            let HoleID = `hole${i}`;
            let HoleIDPic = `holePic${i}`;

            let div = document.createElement('div');
            let img = document.createElement('img');

            div.id = HoleID;
            img.id = HoleIDPic;
            img.src = "someimage.png";

            // put image element in div
            div.appendChild(img);
            // put div in section
            sectionHoles.appendChild(div);

            // adding event listener to the img element
            document.getElementById(HoleIDPic).addEventListener('click', function(){
                alert(HoleIDPic + 'clicked');
            });
        }
   }
    </script>
</body>
</html>
Shine J
  • 798
  • 1
  • 6
  • 11
  • 1
    Thank you for your help! This solved my issue, I'd would up vote you if I could - please accept my gratitude instead! Cheers! – Chris Apr 17 '20 at 15:04
  • 1
    Could you add some information about *how* this solves the problem? I'm glad that Chris thinks this solves his issue, but other readers won't be able to read it easily without text. – Maarten Bodewes Apr 19 '20 at 23:14