072DATA

개인 프로젝트 - 간단한 영화 정보 검색 사이트 만들기 (HTML, CSS, JavaScript, TMDB API) 본문

FrontEnd/HTML, CSS, JavaScript

개인 프로젝트 - 간단한 영화 정보 검색 사이트 만들기 (HTML, CSS, JavaScript, TMDB API)

0720 2024. 7. 25. 19:05

안녕

오늘은 캠프에서 개인과제( 개인 프로젝트 )로

영화 정보 검색 사이트를 만들어 본 과정을 작성해 보겠습니다.


개발 환경

  • Visual Studio Code
  • Github

사용 기술

     프론트엔드

  • Javascript
  • Html/Css

외부 API

  • TMDB API

주요 기능

  • 영화 검색
  • 영화 ID값 가져오기

페이지 디자인

 

 

 

 

 

먼저 구조는 네비게이션바와 영화 리스트 두개의 div로 나누었습니다

전체적인 분위기와 색상은 왓챠를 고려해서 비슷한 색감으로 디자인 했습니다.

 

 

네비게이션 바에서 왼쪽 상단 로고와 검색창을 같은 div로 묶고

로그인/회원가입 버튼도 다른 div에 묶어서

 

    display: flex;
    flex-wrap: inherit;
    align-items: center;
    justify-content: space-between;

 

flex를 사용하고 justify-content : space-between으로 양쪽에 배치했습니다.

 

 

 

로그인/회원가입/검색창 CSS

.SearchBar {
  color: white;
  height: 35px;
  width: 300px;
  background-color: rgb(36, 36, 36);
  border-radius: 5px;
  border: 1px solid rgb(128, 128, 128);
}


.ButtonAreaButton1 {
  border-radius: 5px;
  width: 60px;
  height: 30px;
  font-size: 12px;
  color: white;
  border: none;
  background-color: rgb(24, 24, 24);
}
.ButtonAreaButton1:hover {
  background-color: rgb(61, 61, 61);
}
.ButtonAreaButton2 {
  border-radius: 5px;
  width: 60px;
  height: 30px;
  font-size: 12px;
  color: white;
  border: none;
  background-color: rgb(255, 6, 122);
}
.ButtonAreaButton2:hover {
  background-color: rgb(255, 39, 140);
}

 

 

그리고 영화 리스트는 해당 이미지처럼 나열해주었는데 Boostrap의 card를 가져와서 커스텀해주었습니다.

 

 

 영화 리스트 CSS

<style>
    body {
      background-color: black;
    }
    .main {
      width: 1600px;
      margin: 20px auto 0px auto;
      color: rgb(85, 85, 85);
      padding: 100px;
      background-color: black;
      background-position: center;
      background-size: cover;
    }
    .card {
      cursor: pointer;
      width: 250px;
      border: 1px solid rgb(80, 80, 80);
      color: white;
      transition: transform 0.3s ease;
    }
    .card:hover{
        transform: scale(1.05);
    }
</style>
<body>
    <div class="main">
      <div id="card" class="row row-cols-1 row-cols-md-5 g-4"></div>
    </div>
<body>

 

그리고 영화 리스트는 해당 이미지처럼 나열해주었는데 Boostrap의 card를 가져와서 커스텀해주었습니다.

 

자세한 내용은 해당 포스팅 링크 확인

https://0723-0725.tistory.com/25

 

나만의 추억 앨범 만들기 - 페이지 디자인편(Bootstrap, HTML, CSS)

안녕저는 이제 추억 앨범을 만들어 볼건데 오늘은 디자인 위주로 작성해 보겠습니다. 사실 이미 진행한 프로젝트이지만 제대로 기록하기 위해 블로그에 남겨볼까 합니다.    먼저 보면 좋

0723-0725.tistory.com

 

 


TMDB API 호출 

const options = {
  method: "GET",
  headers: {
    accept: "application/json",
    Authorization:
      "Bearer 나의 키값",
  },
};

function MoviesData() {
  //fetch로 데이터 가져오고
  fetch(
    "https://api.themoviedb.org/3/tv/top_rated?language=en-US&page=1",
    options
  )
  .then((response) => response.json())
  .then((response) => {
    //응답된 데이터 담아주기
    console.log(response)
    const Movies = response.results;
    SearchMovie(Movies);
  })
  .catch((err) => console.error(err));
}

 

 

 

 

 

options 안에 데이터 요청 방식, 어떠한 형식으로 응답할지 담아서

Bearer 토큰을 사용하여 인증합니다

 

 

 

해당 데이터가 담긴 URL과 options를 사용해 API 요청을 보내고

응답된 데이터를 가지고 필요한 데이터를 Movies에 저장하며

Movies를  SearchMovie함수의 매개변수로 보내줍니다.

 


검색 기능

SearchMovie() 

영화를 검색한 값과 데이터 값이 일치하는 데이터를 가져오는 함수

 

const SearchMovie = (Movies) => {
  const SearchInput = document.getElementById("searchInput");
  const SearchVal = SearchInput.value.toLowerCase();

  const filteredMovies = Movies.filter((movie) => {
    const MoviesTitle = movie["name"].toLowerCase();
    // 각 영화의 제목을 가져와서 검색 값을 포함하면 데이터를 리턴
    // include는 빈 공간이 있으면 true로 인식하기 때문에 모든 정보가 보여짐
    return MoviesTitle.includes(SearchVal);
  });
  return CreateList(filteredMovies);
};


실행 순서

 

 

 

1. *documnet.getElementById를 사용하여 검색 창의 결과를 가져오고 해당

검색 결과를 *toLowerCase를 사용하여 모두 소문자로 변환합니다.

 

2. 앞서 MoviesData에서 보내준 매개변수 Movies를 *filter 메소드와 

*includes를 사용해 검색 값과 Movies의 영화 제목이 일치하면 새로운 배열을 return 합니다.

 

 

 

간단한 용어 설명

* filter :   배열의 각 요소를 테스트하여 조건을 만족하는 요소만 포함된 새 배열을 반환함

* toLowerCase : 모든 영문자를 소문자로 변환함

* includes : 배열이 특정 값을 포함하고 있는지 여부를 확인하여, true 또는 false를 반환함 (includes는  빈 값을 무조건 true로 반환)

*document.getElementById : 지정한 ID를 가진 HTML 요소를 반환함 ( *DOM API의 일부)

*DOM : 웹 페이지의 구조와 내용을 프로그래밍적으로 조작할 수 있도록 해주는 API

 

 

CreateList() 

필터링된 영화 배열을 HTML 카드 형태로 변환하여 지정된 요소에 추가하는 함수

 

const CreateList = (filteredMovies) => {
  // console.log("지금 HTML 생성에 있습니다");
  const movieListArea = document.getElementById("card"); //영화 리스트를 뿌려줄 곳
  movieListArea.innerHTML = "";

  filteredMovies.forEach((filteredmovie) => {
    const listItem = document.createElement("div");
    listItem.id = "moviesContainer"; // div id 값을 설정
    listItem.className = "cards"; // div 클래스 값을 설정

    const overview = substringOverview(filteredmovie["overview"], 35);

    // '를 이스케이프 처리하여 replace함수를 사용해 백슬래시(\)로 '를 넣어주어서 완벽한 문자열로 대체해줌
    listItem.innerHTML = `
                <div class="card h-100" onclick="MoiveId( ${
                  filteredmovie["id"]
                }, '${filteredmovie["name"].replace("'", "\\'")}')">
                  <img
                  src="https://image.tmdb.org/t/p/w500${
                    filteredmovie["poster_path"]
                  }"
                  class="card-img-top"
                  alt="..."
                  />
                <div class="card-body">
                  <h5 class="card-title">${filteredmovie["name"]}</h5>
                  <p class="average">${filteredmovie["vote_average"]}</p>
                  <p class="card-text">${overview}</p>
                </div>
            `;
    movieListArea.appendChild(listItem);
  });
};

 

실행 순서

 

 

1. movieListArea 변수에 id가 "card"인 HTML 요소를 선택하고

 

=> 영화 데이터를 뿌려줄 공간

 

2. movieListArea.*innerHTML = "";로 기존의 내용을 지워줌

 

=>  그래야 기존 데이터와 중복되지 않고 새로운 데이터를 렌더링함

 

3. filteredMovies 배열의 각 영화에 대해 *forEach 메소드를 사용하여 반복 처리하고

각 영화에 대해 새로운 div 요소를 생성한 뒤 ID와 클래스를 설정함

 

 

 

 

4.  *innerHTML을 사용하여 영화 카드의 HTML 구조를 정의한 후에

   영화 ID를 클릭 이벤트로 처리하기 위해 *onclick 핸들러를 추가함

const MoiveId = (movieId, movieName) => {
  alert(movieName + "의 id 값은 : " + movieId);
};

 

그리하여 매개변수로 받은 제목과 ID를 *alert로 출력해줌

 

 

5. 생성한 div 요소를 movieListArea에 추가함

 

간단한 용어 설명

* innerHTML :   HTML 요소의 콘텐츠를 문자열 형태로 가져오거나 설정하는 프로퍼티

* forEach : 배열의 각 요소에 대해 제공된 콜백 함수를 실행

* onclick : HTML 요소가 클릭될 때 실행될 자바스크립트 함수를 지정하는 이벤트 핸들러

* document.createElement  : 지정한 태그 이름으로 새로운 HTML 요소를 생성하는 메서드

* alert : 브라우저에서 사용자에게 메시지를 표시하는 경고 창을 띄우는 함수

 

아 그리고 버튼을 따로 만들지 않고 input의 값이 변경되면 함수가 실행 되도록

*이벤트 리스너를 사용하여 로직을 구현했다.

document.addEventListener("DOMContentLoaded", () => {
  MoviesData();

  // 입력 필드의 값이 변경될 때마다 SearchMovie 함수를 호출
  const searchInput = document.getElementById("searchInput");
  searchInput.addEventListener("input", () => MoviesData());
});

 

*addEventListener : 특정 이벤트가 발생할 때 실행될 함수를 지정하는 메서드입니다.

 

그 외에도 검색창 기본 커서 함수, 영화 설명 데이터 요약 함수를 만들었다.

 

검색 결과 및 ID 값

 

 

오류

 

어떠한 영화를 눌렀을 때 해당 영화의 ID 값을 출력하는 ALERT가 안나와서

샅샅히 수사하였는데 두개의 영화가 같은 특징을 가지고 있었다

바로 영화 제목에 작은 따옴표(')가 존재하는 것이었다. 

그리하여  *replace함수를 사용해 백 슬래시(\)로 '를 넣어주어 이스케이프 처리를 완료하였다.

 

 

이스케이프 처리 : 문자열에서 특별한 의미를 가지는 문자를

문자 그대로 표현하기 위해 백슬래시(\)를 사용하는 과정을 말한다

 

*replace : 문자열에서 특정 패턴을 찾아 다른 문자열로 교체하는 메서드

 

마무리 느낀점

 

뭔가 포스팅으로 보면 간단하게 구현하여 얼마 안걸렸을 것 같지만

주어진 과제에서 필수 구현 사항들이나 필수로 사용하는 메소드들의 제약이 있어서이틀 동안 열심히 만들었다 해당 프로젝트를 진행하면서그동안 강의로 들었던 부분을 직접 사용해보니까2배는 더 빠삭하게 해당 기능들을 이해할 수 있던 것 같다 오류도 몇 번 해결해 보면서 내가 조금씩 성장하는게 느껴진다 내일도 킵고잉