Coding/내일배움캠프

[내일배움캠프] Node.js 4기 TIL | 내배캠 최고 평점 영화 콜렉션 업데이트 | Day 12 | 24.01.09.(화)

_Woo_ 2024. 1. 9. 21:44

https://sjwoo1999.github.io/FC-NBC-MOVIE-SEARCH

 

내배캠 최고 평점 영화 콜렉션

 

sjwoo1999.github.io

 

**설명:**

- 이전 코드에서는 img 태그 내부에 `onClick="imgClick()"` 속성을 직접 추가했는데,
이는 동적으로 생성된 요소에는 직접 이벤트 핸들러를 추가할 수 없기 때문에 작동하지 않습니다.
- 수정된 코드에서는 먼저 img 태그를 선택한 후, `addEventListener` 메서드를 사용하여
클릭 이벤트 리스너를 연결합니다. 이렇게 하면 동적으로 생성된 요소에도 정상적으로
이벤트 핸들러가 적용됩니다.

**추가 참고:**

- `renderCards` 함수 내에서 `card.innerHTML`에 직접 img 태그를 포함하는 방식은
코드의 가독성과 유지보수 측면에서 좋지 않을 수 있습니다.
가능하면 `createElement`와 `appendChild`를 사용하여 img 태그를 생성하는 방식을
사용하는 것이 좋습니다.

**이렇게 수정하면 img 태그를 클릭했을 때 imgClick() 함수가 정상적으로 실행되는 것을
확인할 수 있습니다.**

**도움이 되었기를 바랍니다!**

 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>내배캠 최고 평점 영화 콜렉션</title>
    <script>
      const options = {
        method: "GET",
        headers: {
          accept: "application/json",
          Authorization:
            "my_api_key",
        },
      };

      const getImageUrl = (path, size = 400) => {
        return `https://image.tmdb.org/t/p/w${size}${path}`;
      };

      let movies;

      function handleSearch(event) {
        event.preventDefault(); // Prevent form submission
        const searchWord = document.querySelector("#search-input").value;

        // Check if movies is defined
        if (!movies) {
          return; // Exit the function if movies is not defined
        }

        const filteredMovies = movies.filter((movie) => {
          return movie.title.toLowerCase().includes(searchWord.toLowerCase());
        });

        renderCards(filteredMovies);
      }

      function renderCards(movies) {
        const cardList = document.querySelector(".card-list");
        cardList.innerHTML = ""; // Clear existing cards

        movies.forEach((movie) => {
          const card = document.createElement("div");
          card.classList.add("movie-card");

          card.innerHTML = `
          <img src="${getImageUrl(movie.poster_path)}" alt="${movie.title}">
          <h3 class="movie-title">${movie.title}</h3>
          <p>${movie.overview}</p>
          <p>Rating: ${movie.vote_average}</p>
        `;

          cardList.appendChild(card);
        });
      }

      fetch(
        "https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1",
        options
      )
        .then((response) => response.json())
        .then((response) => {
          // 영화 정보에서 필요한 정보를 추출한다.
          const adult = response.adult;
          const backdrop_path = response.backdrop_path;
          const genre_ids = response.genre_ids;
          const id = response.id;
          const original_language = response.original_language;
          const original_title = response.original_title;
          const overview = response.overview;
          const popularity = response.popularity;
          const poster_path = response.poster_path;
          const release_data = response.release_data;
          const title = response.title;
          const video = response.video;
          const vote_average = response.vote_average;
          const vote_count = response.vote_count;

          // 추출한 정보를 하나의 객체에 넣는다.
          const movie = {
            adult,
            backdrop_path,
            genre_ids,
            id,
            original_language,
            original_title,
            overview,
            popularity,
            poster_path,
            release_data,
            title,
            video,
            vote_average,
            vote_count,
          };

          // 객체를 콘솔에 출력한다.
          console.log(movie);

          const data = JSON.stringify([response]);

          movies = response.results;

          console.log(movies);

          movies.forEach((movie) => {
            const cardList = document.querySelector(".card-list");
            const card = document.createElement("div");
            card.classList.add("movie-card");

            card.innerHTML = `
              <img src="${getImageUrl(movie.poster_path)}" alt="${movie.title}">
              <h3 class="movie-title">${movie.title}</h3>
              <p>${movie.overview}</p>
              <p>Rating: ${movie.vote_average}</p>
            `;

            // 이미지에 클릭 이벤트 리스너 추가
            card.querySelector("img").addEventListener("click", () => {
              alert(`영화 id : ${movie.id}`);
            });

            cardList.appendChild(card);
          });
        })
        .catch((err) => console.error(err));
    </script>
  </head>
  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    .body {
      background: url("../assets/bg.png") center/cover no-repeat;
      min-height: 100vh;
    }

    .card-list {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      justify-content: center;
    }

    .movie-card {
      box-shadow: 0 3px 6px rgba(0, 0, 0, 0.12), 0 3px 6px rgba(0, 0, 0, 0.24);
      margin: 20px;
      padding: 20px;
      width: 300px;
      justify-self: center;
      background-color: bisque;
      border-radius: 10px;
      cursor: pointer;
      user-select: none;
    }

    .movie-card img {
      width: 100%;
      border-radius: 10px;
    }

    header {
      background-color: #ffe194;
      display: flex;
      justify-content: center;
      align-items: center;
      padding: 30px 0;
    }

    .search {
      width: 100%;
      display: flex;
      justify-content: center;
      padding: 20px 0;
      border-bottom: 1px solid black;
    }

    .search label {
      font-size: 25px;
    }

    .search input {
      margin-left: 20px;
      min-width: 200px;
      padding: 5px 10px;
    }

    .search button {
      margin-left: 10px;
      padding: 5px;
    }

    h3 {
      margin-bottom: 10px;
    }
  </style>
  <body>
    <header>
      <h1>내배캠 최고 평점 영화 콜렉션</h1>
    </header>

    <script>
      const searchInput = document.querySelector("#search-input");

      if (searchInput) {
        searchInput.addEventListener("input", handleSearch);

        searchInput.addEventListener("keyup", function (event) {
          if (event.keyCode === 13) {
            event.preventDefault();
            alert("ENTER !!!");
          }
        });
      }
    </script>

    <form class="search" onsubmit="handleSearch(event)">
      <label>영화 검색 : </label>
      <input
        type="text"
        id="search-input"
        placeholder="영화 제목을 검색해 보세요"
      />
      <button type="submit" id="search-btn">검색</button>
    </form>
    <br />
    <section class="card-list"></section>
  </body>
</html>