0

I' building this website for a uni project and am running into the following problem. I have an array of movies displayed in a flecxbox on the homepage. I need to run some code on clicking the movie posters, so I added an eventlistener to the movie div. But now when I run the website (without clicking anywhere) the eventlistener for each movie is triggered. And when I then click on the images, nothing happens... What am I doing wrong here? Thanks in advance for helping!!

class Movie {
  constructor(title, image, description, duration, release, age, schedule, seats) {
    this.title = title;
    this.image = image;
    this.description = description;
    this.duration = duration;
    this.release = release;
    this.age = age;
    this.schedule = schedule; //dictionary met alle tijden per dag.
    this.seats = seats;
  }
}

const blankMovie = new Movie(
  "Blank",
  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQwAAAC8CAMAAAC672BgAAAAA1BMVEWxrq37BefPAAAARklEQVR4nO3BAQEAAACAkP6v7ggKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAbFjAAB3KzK6gAAAABJRU5ErkJggg==",
  "blank",
  "blank"
);

var allMovies = [blankMovie, blankMovie, blankMovie, blankMovie];
const homePage = document.getElementById("movie-slider");

for (let i = 0; i < allMovies.length; i++) {
  const movieDiv = document.createElement("div");
  movieDiv.className = "movie-banner";

  const movieTitle = document.createElement("span");
  movieTitle.className = "movie-banner__title";
  movieTitle.textContent = allMovies[i].title;

  const movieImage = document.createElement("img");
  movieImage.className = "movie-banner__image";
  movieImage.src = allMovies[i].image;

  const movieDur = document.createElement("span");
  movieDur.className = "movie-banner__desc";
  movieDur.textContent = allMovies[i].duration;

  homePage.appendChild(movieDiv);
  movieDiv.appendChild(movieTitle);
  movieDiv.appendChild(movieImage);
  movieDiv.appendChild(movieDur);

  movieDiv.addEventListener("click", console.log(i));
}
body {
  margin: 0;
  font-family: 'Teko', sans-serif;
}

#movie-slider {
  display: flex;
  flex-direction: row;
  overflow: auto;
  gap: 10px;
  padding: 0% 10%;
}

#movie-slider::-webkit-scrollbar {
  height: 0;
}

.movie-banner {
  flex-basis: 250px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
}

.movie-banner__image {
  object-fit: cover;
  height: 100px;
}

.movie-banner__title {
  color: wheat;
  text-align: center;
  font-family: 'Bebas Neue', cursive;
  font-size: 2em;
  padding: 10px
}

.movie-banner__desc {
  color: wheat;
  font-size: 1.3em;
  text-align: center;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Movie Tickets</title>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Teko:wght@300&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="/css/index.css">
  <link rel="stylesheet" href="/css/general.css">
  <!--<link rel="icon" href="../images/general/logo.jpg">-->
</head>

<body>
  <article class="content">
    <section id="movie-slider">
    </section>
  </article>
  <script src="/js/index.js" type="module"></script>
  <script src="/js/general.js" type="module"></script>
</body>

</html>
Jord van Eldik
  • 351
  • 2
  • 10
  • 2
    You don't want to call the console log when you add the event listener, simply pass a reference to a function to be triggered. A simple solution would be `() => console.log("Some text")` – Tamir Abutbul Apr 07 '23 at 11:49
  • 2
    You have to pass a function reference to `addEventListener()`. You're passing the return value of `console.log()`, which is `undefined`. Wrap your log call in a function: `addEventListener("click", function() { console.log(i); })` – Pointy Apr 07 '23 at 11:49
  • 2
    You are assigning the return value of console.log() to the event handler. Instead assign a function to it.`movieDiv.className = "movie-banner"; movieDiv.dataset.index = i; movieDiv.addEventListener("click", (e) => console.log(e.target.closest('.movie-banner').dataset.index')));` but please delegate: `homePage.addEventListener("click", (e) => console.log(e.target.closest('.movie-banner').dataset.index')));` – mplungjan Apr 07 '23 at 11:50
  • 1
    @mplungjan perhaps, though the loop index that the OP is logging is declared with `let` – Pointy Apr 07 '23 at 11:51

1 Answers1

-1

You need to wrap the click logic in a function handler:

class Movie {
  constructor(title, image, description, duration, release, age, schedule, seats) {
    this.title = title;
    this.image = image;
    this.description = description;
    this.duration = duration;
    this.release = release;
    this.age = age;
    this.schedule = schedule; //dictionary met alle tijden per dag.
    this.seats = seats;
  }
}

const blankMovie = new Movie(
  "Blank",
  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQwAAAC8CAMAAAC672BgAAAAA1BMVEWxrq37BefPAAAARklEQVR4nO3BAQEAAACAkP6v7ggKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAbFjAAB3KzK6gAAAABJRU5ErkJggg==",
  "blank",
  "blank"
);

var allMovies = [blankMovie, blankMovie, blankMovie, blankMovie];
const homePage = document.getElementById("movie-slider");

for (let i = 0; i < allMovies.length; i++) {
  const movieDiv = document.createElement("div");
  movieDiv.className = "movie-banner";

  const movieTitle = document.createElement("span");
  movieTitle.className = "movie-banner__title";
  movieTitle.textContent = allMovies[i].title;

  const movieImage = document.createElement("img");
  movieImage.className = "movie-banner__image";
  movieImage.src = allMovies[i].image;

  const movieDur = document.createElement("span");
  movieDur.className = "movie-banner__desc";
  movieDur.textContent = allMovies[i].duration;

  homePage.appendChild(movieDiv);
  movieDiv.appendChild(movieTitle);
  movieDiv.appendChild(movieImage);
  movieDiv.appendChild(movieDur);

  movieDiv.addEventListener("click", function() {
    console.log(i)
  });
}
body {
  margin: 0;
  font-family: 'Teko', sans-serif;
}

#movie-slider {
  display: flex;
  flex-direction: row;
  overflow: auto;
  gap: 10px;
  padding: 0% 10%;
}

#movie-slider::-webkit-scrollbar {
  height: 0;
}

.movie-banner {
  flex-basis: 250px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
}

.movie-banner__image {
  object-fit: cover;
  height: 100px;
}

.movie-banner__title {
  color: wheat;
  text-align: center;
  font-family: 'Bebas Neue', cursive;
  font-size: 2em;
  padding: 10px
}

.movie-banner__desc {
  color: wheat;
  font-size: 1.3em;
  text-align: center;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Movie Tickets</title>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Teko:wght@300&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="/css/index.css">
  <link rel="stylesheet" href="/css/general.css">
  <!--<link rel="icon" href="../images/general/logo.jpg">-->
</head>

<body>
  <article class="content">
    <section id="movie-slider">
    </section>
  </article>
  <script src="/js/index.js" type="module"></script>
  <script src="/js/general.js" type="module"></script>
</body>

</html>

MDN web docs:

addEventListener(type, listener)

listener:

The object that receives a notification (an object that implements the Event interface) when an event of the specified type occurs. This must be null, an object with a handleEvent() method, or a JavaScript function. See The event listener callback for details on the callback itself.

Miss Skooter
  • 803
  • 10
  • 22