1

I am trying to make my site responsive to handheld actions. I have four images, all with the class="grid-photos". I am trying to make the photos expand when clicked, and close when clicked again.

        <div class="grid-container">
         <img class="grid-photos">
         <img class="grid-photos">
         <img class="grid-photos">
         <img class="grid-photos">

As of now I can get it to work only with the first image using this Javascript

const gridPhotos = document.querySelector(".grid-photos");

document.querySelectorAll(".grid-photos").forEach((item) => {
  item.addEventListener("click", (event) => {
    gridPhotos.classList.toggle("expander");
  });
});

I have tried querySelectorAll with [i] but to no avail.

Thank you for any help

  • Just use `item` or `event.target` instead of `gridPhotos` before `classList`. – Heretic Monkey Feb 25 '21 at 14:51
  • Does this answer your question? [Javascript get "clicked" element addEventListener](https://stackoverflow.com/questions/30786154/javascript-get-clicked-element-addeventlistener) – Heretic Monkey Feb 25 '21 at 14:56
  • 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 25 '21 at 15:04

2 Answers2

2

The problem is that your variable gridPhotos is a collection of all your grid photos. So when you call .classList on it you'll get an error about it being undefined.

What you need to to is get the correct element from the event instead. event.target will return the element that was clicked so you can use that to add a class to the correct image.

document.querySelectorAll(".grid-photos").forEach((item) => {
  item.addEventListener("click", (event) => {
    event.target.classList.toggle("expander");
  });
});
.expander {
  border: 4px solid green; /* Added to highlight which one was clicked */
}
<div class="grid-container">
  <img class="grid-photos" src="https://lh6.googleusercontent.com/-l7M0ldZDNZs/AAAAAAAAAAI/AAAAAAAAAAA/ACHi3rf7tyiXmVY3yNjeGjVZCZdKL2qObw/photo.jpg?sz=32">
  <img class="grid-photos" src="https://lh6.googleusercontent.com/-l7M0ldZDNZs/AAAAAAAAAAI/AAAAAAAAAAA/ACHi3rf7tyiXmVY3yNjeGjVZCZdKL2qObw/photo.jpg?sz=32">
  <img class="grid-photos" src="https://lh6.googleusercontent.com/-l7M0ldZDNZs/AAAAAAAAAAI/AAAAAAAAAAA/ACHi3rf7tyiXmVY3yNjeGjVZCZdKL2qObw/photo.jpg?sz=32">
  <img class="grid-photos" src="https://lh6.googleusercontent.com/-l7M0ldZDNZs/AAAAAAAAAAI/AAAAAAAAAAA/ACHi3rf7tyiXmVY3yNjeGjVZCZdKL2qObw/photo.jpg?sz=32">
</div>
Karl-Johan Sjögren
  • 14,076
  • 7
  • 55
  • 62
0

You wrong selector querySelector select just 1, querySelectorAll select all items example:

const gridPhotos = document.querySelectorAll(".grid-photos");

gridPhotos.forEach(function (item) {
  item.onclick = function()
  {
    this.classList.toggle("expander");
  };
});
<div class="grid-container">
  <img class="grid-photos" src="https://via.placeholder.com/150">
  <img class="grid-photos" src="https://via.placeholder.com/150">
  <img class="grid-photos" src="https://via.placeholder.com/150">
</div>
Simone Rossaini
  • 4,586
  • 1
  • 5
  • 24