0

I'm trying to implement some modal images and am having some trouble making a forEach work on an array of elements.

This is my variables declaration:

// Get the modal
var modal = document.getElementsByClassName("modal")[0]

// Get the modal trigger image and the modal content image
var img = document.getElementsByClassName("img-to-modal")
var modalImg = document.getElementsByClassName("modal-img")[0]

Why does this work?:

// Insert the image into the modal
for (i = 0; i < img.length; i++) {
    img[i].addEventListener("click", function () {
        modal.style.display = "block"
        modalImg.src = this.src
        
    })
}

And this doesn't? (nothing happens when I click the images):

// Insert the image into the modal
img.forEach(function (element) {
    element.addEventListener("click", function () {
        modal.style.display = "block"
        modalImg.src = this.src        
    })
})

Just for future reference, what would be the best way/syntax to loop through an array of elements to work with event handlers? Is there any to achieve this using the 'img.onclick...' syntax?

  • Use [event delegation](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_delegation) instead of assigning multiple events — it’s more maintainable, and applies to dynamically added elements. E.g., use an [event argument](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#The_event_listener_callback)’s [`target`](https://developer.mozilla.org/en-US/docs/Web/API/Event/target). See [the tag info](https://stackoverflow.com/tags/event-delegation/info) and [What is DOM Event delegation?](https://stackoverflow.com/q/1687296/4642212). – Sebastian Simon Feb 17 '21 at 22:07
  • @SebastianSimon this worked perfectly. Thanks!! :) – Tiago Brandão Feb 17 '21 at 22:44
  • @SebastianSimon just one question. The 'this' keyword won't work with event delegation, I have to use always 'event.target', right? – Tiago Brandão Feb 17 '21 at 22:52
  • Yes, basically. – Sebastian Simon Feb 17 '21 at 22:54

1 Answers1

0

I think forEach is not working on HTML Collections. You have to convert it to an array first. Array.from(collection).forEach(function (element) { console.log(element) });

If you select the images with querySelectorAll it could work without converting i guess.

tdesero
  • 101
  • 5