프로젝트

[자바스크립트] TMDB api 사용해 영화 검색 기능 구현

ejunyang 2024. 4. 30. 21:16


https://ejunyang.tistory.com/entry/PP-TMDB-api-%EC%82%AC%EC%9A%A9%ED%95%B4-%EC%98%81%ED%99%94-%EB%AA%A9%EB%A1%9D-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0

 

[P.P] TMDB api 사용해 영화 목록 가져오기

https://ejunyang.tistory.com/entry/PP-TMDBThe-Movie-DB-api-%EC%82%AC%EC%9A%A9 [P.P] TMDB(The Movie DB) api 사용🚩 영화 검색 사이트 구현 Javascript과정을 마무리하며, JS 문법의 핵심을 적용해 볼 수 있는 영화 검색 사이

ejunyang.tistory.com


 

✅  필수 사항

1. jQuery 라이브러리 사용없이 순수 바닐라 자바스크립트 사용하기

2. TMDB 오픈 API를 이용하여 인기영화 데이터 가져오기

3. 영화정보 카드 리스트 UI 구현

- 카드에는 title(제목), overview(내용 요약), poster_path(포스터 이미지 경로), vote_average(평점) 이렇게 4가지 정보가 필수

- 카드 클릭 시에는 클릭한 영화 id 를 나타내는 alert 창을 띄우기

 

4. 영화 검색 UI 구현

5. Javascript 문법 요소를 이용하여 구현

- const와 let만을 이용한 변수 선언 필수

- 화살표 함수

- 배열 메소드 : 하기 예시 중 2개 이상 사용

  • forEach
  • map
  • filter
  • reduce
  • find

- DOM 제어하기 : 아래 api 목록 중 2개 이상 사용하기

document.createElement(tagName) //새로운 HTML 요소를 생성합니다.
document.getElementById(id) //id 속성을 기준으로 요소를 선택합니다.
document.getElementsByTagName(name) //태그 이름을 기준으로 요소를 선택합니다.
document.getElementsByClassName(name) //클래스 이름을 기준으로 요소를 선택합니다.
document.querySelector(selector) //CSS 선택자를 이용하여 요소를 선택합니다.
document.querySelectorAll(selector) //CSS 선택자를 이용하여 모든 요소를 선택합니다.
element.innerHTML //해당 요소 내부의 HTML 코드를 변경합니다.
element.textContent //해당 요소 내부의 텍스트를 변경합니다.
element.setAttribute(attr, value) //해당 요소의 속성 값을 변경합니다.
element.getAttribute(attr) //해당 요소의 속성 값을 가져옵니다.
element.style.property //해당 요소의 스타일 값을 변경합니다.
element.appendChild(child) //해당 요소의 하위 요소로 child를 추가합니다.
element.removeChild(child) //해당 요소의 하위 요소 중 child를 삭제합니다.
element.classList.add(class) //해당 요소의 클래스에 새로운 클래스를 추가합니다.
element.classList.remove(class) //해당 요소의 클래스 중에서 특정 클래스를 제거합니다.
element.classList.toggle(class) //해당 요소의 클래스 중에서 특정 클래스를 추가 또는 제거합니다.
element.addEventListener(type, listener) //해당 요소에서 이벤트가 발생했을 때 호출할 함수를 등록합니다.
element.removeEventListener(type, listener) //해당 요소에서 등록된 함수를 제거합니다.
event.preventDefault() //이벤트가 발생했을 때 기본 동작을 취소합니다.
event.stopPropagation() //이벤트의 버블링을 방지하기 위해 이벤트 전파를 중지합니다.
window.location.href //현재 페이지의 URL을 가져옵니다.
window.alert(message) //경고 메시지를 출력합니다.
window.confirm(message) //확인 메시지를 출력하고 사용자의 답변에 따라 Boolean 값을 반환합니다.

 


 

 

🔥 완성

 

각 영화 카드를 눌렀을 때 고유 id가 alert 뜨기도 했고, 영화 제목을 검색했을 때 해당 영화만 뜨도록 구현도 완료했다!

순수 바닐라는 너무 오랜만이고 실무에서도 제이쿼리만 쓰다보니 너무 헷갈리고 메서드도 잘 기억이 안난다

그래서 요즘은 알고리즘 문제들만 주구장창 푸는 중이다. 풀다보니 메서드 기억이 새록새록 올라와서 요즘 꽤 재미 붙이고있다.

 

 


 

👀 영화 검색하기

function searchMovies() {

    const mycards = document.querySelector('#mycards'); //카드 품은 wrap
    const movieCard = mycards.querySelectorAll('.col'); //카드
    const searchInput = document.querySelector('#searchInput'); //입력칸
    const searchBtn = document.querySelector("#searchBtn"); //검색버튼

}

 

사용자가 검색한 영화 제목이 포함되어있지 않은 카드들은 display:none; 하는 코드를 짜봤다. 우선, dom요소들을 가져오고 각 변수에 선언해준다. 검색 기능이 아예 감도 안잡힐 때 🧑🏻‍🦱은채 튜터님한테 물어봤는데 querySelector로 html 요소들을 가지고와서 작업하면 편리하다고 말씀해주셨다. 전에는 주구장창 getElementById만 써서 특정 아이디가 아니면 동작을 안해서 골머리를 썼는데.. 

 

function searchHandle(e){
        e.preventDefault();
        let userInput = searchInput.value;

        movieCard.forEach((el) => {
            el.classList.remove('hidden');
            let movieTitle = el.getElementsByTagName('h2')[0].innerText;
            if (!movieTitle.toLowerCase().includes(userInput)) {
                el.classList.add("hidden");
            }
        })
    }

 

let userInput = searchInput.value;

우선 검색 버튼을 눌렀을 때 실행하는 이벤트 핸들러를 만들어주고 userInput 변수에 사용자가 입력한 값을 할당해준다. 

 

movieCard.forEach((el) => {}

forEach문으로 이미 만들어진 무비 카드들에서 사용자가 입력한 값과 영화 제목이 일치하면 일치한 영화는 제외하고 나머지 카드들은 hidden 클래스는 add하면 된다.

 

let movieTitle = el.getElementsByTagName('h2')[0].innerText;

각 카드 안 <h2>태그의 0번째 텍스트를 movieTitle 변수에 할당해준다. 

 

<div class="col">
        <img src=${image} class="card-img-top" alt="포스터">
        <div class="card-body">
            <h2 class="card-title">${title}</h2>
            <p class="card-text">${overview}</p>
            <p class="card-vote">${vote}</p>
        </div>
    </div>

 카드가 위 구조로 짜여져 있다. <h2>태그는 .card-title 로 각 카드의 영화 제목을 담고있다.

 

if (!movieTitle.toLowerCase().includes(userInput)) {
   el.classList.add("hidden");
}

그리고 toLowerCase()로 대소문자 관계없이 값을 받을 수 있도록 하고, 사용자가 입력한 값과 영화 제목이 일치하지 않을 경우 카드를 모두 숨겨준다. hidden 클래스는 css파일에 미리 만들어두고, 간편하게 classList로 추가했다가 삭제했다. 

 

searchBtn.addEventListener("click", searchHandle);

마지막으로 검색 버튼에 이벤트 리스너를 붙여 클릭했을 때 위에 생성한 이벤트 핸들러가 동작하게 해주면 끝 !!

 

 


 

 

 if (movieTitle === movieTitleArr[i]) { // 배열 === 스트링 false
    document.getElementById('swipe').style = 'display:none';
    document.getElementById('title-area').style = 'display:none';
    movieArr[i].style = 'display:block';
}

처음 코드는 이렇게 짰었는데 피드백을 받고 위에 설명한 코드대로 수정했다. 이 코드는 특정 아이디 값의 html 요소에 직접적으로 style을 먹여줬다. 피드백받은 사항 중 하나였고 다시보니 코드가 그리 깨끗해 보이진 않는 것 같다.