본문 바로가기
내일배움캠프/Today I Learned

[TIL 2023.05.29] 영화 검색 페이지 만들기 (GOE’s CINEMA)

by 괴코딩 2023. 5. 30.

목차

💻오늘 배운 내용

❓발생한 이슈/고민

💡해결과정

🧐궁금점과 부족한 내용

📋레퍼런스

 

💻오늘 배운 내용


CSS grid 사용

그리드 사용 방법은 의외로 간단했다.

display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-column-gap: 2%;

display를 grid로 두고 columns(가로), rows(세로) 값을 설정해주면 된다.

만약 간격을 주고싶다면 grid-column-gap 또는 grid-row-gap을 사용

fr이라는 단위는 fraction(뜻은 여기로)이라는 의미로 숫자 비율대로 트랙의 크기를 나눈다.

 

오픈 api를 이용해 바닐라 자바스크립트로 영화 카드 생성

결론은 웹개발 종합반에서 배웠던 내용을 응용해서 살짝만 변형한다면 굉장히 간단한 문제 였지만

jquery 금지! 바닐라 자바스키립트 사용!에 너무 겁을 먹어서 상당히 어렵게 돌아 간 것이 아닌가 싶다.

아래에 좀 더 자세히 다루도록 하겠다.

 

❓발생한 이슈/고민


데이터가 불러와지지 않는 문제

데이터를 불러와서 카드 생성은 어떻게 하는 것?

 

💡해결과정


fetch('<https://api.themoviedb.org/3/movie/popular?language=ko&page=1>', options)
  .then((response) => response.json())
  .then((data) => {
    const moviesContainer = document.getElementById('movies');

    while (moviesContainer.firstChild) {
      moviesContainer.removeChild(moviesContainer.firstChild);
    }

    data.results.forEach((movie) => {
      const card = createMovieCard(movie);
      moviesContainer.appendChild(card);
    });
  })
  .catch((err) => console.error(err));

function createMovieCard(movie) {
  // 카드 요소 생성
  const card = document.createElement('div');
  card.classList.add('movie');

  // 포스터 이미지
  const posterUrl = `https://image.tmdb.org/t/p/w500${movie.poster_path}`;
  const poster = document.createElement('img');
  poster.src = posterUrl;
  poster.alt = movie.title;
  card.appendChild(poster);

  // 제목
  const title = document.createElement('h2');
  title.textContent = movie.title;
  card.appendChild(title);

  // 줄거리
  const overview = document.createElement('p');
  overview.textContent = movie.overview;
  card.appendChild(overview);

  // 평점
  const voteAverage = document.createElement('p');
  voteAverage.textContent = `평점 ${movie.vote_average}`;
  card.appendChild(voteAverage);

  return card;
}

 

처음 작성했던 코드다.

html문서에서 영화 카드 요소들을 감싸고 있는 'movies'를 불러온다음 moviesContainer로 선언 while으로 원래 html에 있던 자식요소는 제거한 뒤 createMovieCard 함수로 새로운 영화카드들을 생성하려고 했다.

data.results에는 API에서 받아온 영화 목록 데이터가 있고, forEach하면서 moviesContainer에 createMovieCard 함수로 만든 카드들을 자식요소로 넣는 로직.

 

여기서 createMovieCard 함수는

createElement로 카드 div 태그를 만들고 카드의 appendChild로서 각각 영화 포스터, 영화제목, 영화 줄거리, 영화 평점을 넣어 준 다음 카드를 리턴.

실데로 카드들도 생성되긴 하지만, 너무 길고, 가독성이 별로라고 생각했다. 하지만 더 간단한 방법은 생각이 나지 않았는데

 

같이 공부하고 있던 분의 코드를 보자마자 무릎을 탁 쳤다.

 

fetch(
  'https://api.themoviedb.org/3/movie/now_playing?language=ko&page=1',
  options
)
  .then((response) => response.json())
  .then((response) => {
    document.querySelector('.movie').remove();
    response.results.forEach((movie) => {
      let template = `<div class="movie">
                      <img src="https://image.tmdb.org/t/p/w500${movie.poster_path}" alt="" />
                      <h2 class="movieName">${movie.title}</h2>
                      <p class="movieSum">${movie.overview}</p>
                      <p class="movieRate">평점 ${movie.vote_average}</p>
                      
                    </div>`;

      document
        .querySelector('#movies')
        .insertAdjacentHTML('beforeend', template);
    });
  })
  .catch((err) => console.error(err));

 

이 얼마나 간결하고 깔끔한지..

그렇구나 그냥 백틱으로 템플릿을 만들어 버리면 간단하지… 생성자 함수…

웹종반에서도 했었던건데 왜 이렇게 생각 못했을까. 쿼리셀렉터 만세다.

 

와중에 좀 더 줄여보자면

 

document.querySelector('.movie').remove();

 

요것도 삭제해도 되지않은가. html에도 아예 다 지우고 movie클래스 div만 남겨두면

forEach문 돌리기 전에 뭘 지우고 할 것도 없이 그냥 만들기만 하면 되는 것

효율효율! 굴러라 머리머리!

 

🧐궁금점과 부족한 내용


아직 구현하지 못한 것들

 

검색기능은 어떻게 구현하는 건지 알아봐야한다.

이 부분도 다시 새로 시작하는 것 마냥 감도 안잡힌다.

 

카드를 클릭했을 때 영화 디테일 페이지를 출력해야한다.

 

카드 이미지를 클릭하면 영화 아이디를 알려주는 alert창을 만들어야 한다.

 

홈의 영화 카드들은 자동 슬라이드로 만들고 싶다

 

검색 아이콘 클릭 시 trasition으로 검색창이 점점 길어지며 나타나게 하고 싶다

 

📋레퍼런스


https://nykim.work/59 그리드 만들기

https://hianna.tistory.com/484 요소 제거

https://webruden.tistory.com/655 텍스트 말줄임

반응형