Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

훈돌라

2024-04-26 개인과제 완성..? 본문

카테고리 없음

2024-04-26 개인과제 완성..?

훈돌라 2024. 4. 26. 19:19

필수 조건들은 모두 들어갔다.. CSS 를 할 힘이 남아있지 않다..

 

 

이런 식으로 포스터들이 나열되고, 포스터들은 영화 순위 API 에서 받아온 데이터들을 기반으로

자동 생성되어 html 을 채우게 된다.

 

페이지 상단의 검색창에 검색어를 입력 후 검색 버튼을 누르면 -> ex ) titan 검색

 

 

포스터 제목에 titan 이 포함된 포스터들을 하단에 노출시킨다.

 

대, 소문자도 상관없다. 로직에 검색 시 데이터들을 읽을 때 소문자로 변환하여 읽게 끔 짜두었기 때문이다.

 

 

 

 

 

 

포스터를 클릭 했을 시 경고창에 해당 영화의 ID 값도 출력되게 끔 구현했다.

 

 과제의 필수 조건

1. 제이쿼리 라이브러리 사용 없이 순수 바닐라 스크립트로 구현하기
2. TMDB 오픈 API 를 이용하여 인기 영화 데이터 가져오기
3. 영화정보 카드 리스트 UI 구현하기
4. 영화 검색 UI 구현하기
5. const, let 만을 이용한 변수 선언 / 화살표 함수 1개 이상 사용 / 배열 메소드 2개 이상 / DOM 제어하기 2개 이상

 

배열 메소드 2개 이상을 제외하고는 모두 완료했다,, 머리를 싸매는 중인데 아직은 forEach 밖에 쓰질 못하겠다..

 

 

  .then(response => response.json())
  .then(response => {                           // fetch 불러온거 (API)              
    let movie_list = response.results; // 불러온 데이터를 변수에 할당해준다
    let temp_html = ``; // temp_html 을 아무런 값도 없이 초기화 한다
    movie_list.forEach(doc => {          // 데이터 불러온걸 순회해서 변수들에 넣어준다
      let movietitle = doc['name'].replace(' ','-');  // raplace (' ' , '-') id 의 띄어쓰기는 읽지 않음, 그래서 id 의 띄어쓰기를 - (하이픈) 으로 바꾸면 되지 않을까~ 해서 replace 를 사용했음
      //The Attack of Titan -> The-Attack-of-Titan
      let overview = doc['overview']; //데이터에 변수 지정
      let image = 'https://image.tmdb.org/t/p/w500' + doc['poster_path']; //데이터에 변수 지정
      let vote_average = doc['vote_average']; //데이터에 변수 지정
      let card_id = doc['id']; // 데이터에 변수 지정

 

 let movietitle = doc['name'].replace(' ','-')

 

이 부분에서 상당히 애를 먹었는데, 이유는

 

name 이라는 영화 이름 데이터를 가져왔을 때 id 값에다 지정을 하니 영화 이름 데이터의 띄어쓰기는 인식하지 못했다.

 

설명하자면, The Chosen 이라는 영화와 The Owl 이라는 영화가 있다.

 

근데 ID 값은 띄어쓰기를 인식하지 못하니 이 놈들의 ID 값은 The 가 되는 것이다.

 

 

 

그래서 titan 을 검색하든, hazbin 을 검색하든, 다른 단어를 검색해도 중복되고, 하위에 있는 The Chosen 이라는 영화는 진짜로 무슨

 

지가 무슨 선택받은  자 (The Chosen) 인 것 마냥 계속 노출되게 되는 것이다. (display none 이 적용이 안 됨)

 

요컨데, 중복된 ID 값들은 어떻게 해라, 라는 코드가 없었으니 그랬을텐데, 애초에 중복된 영화 이름은 존재할 수 없으니 name 데이터 전부를 읽어올 방법이 없을까? 하는 고민이 시작된 것이다.

 

 

 

 

li class 의 id 값을 잘 보면 띄어쓰기 까지를 인식하는 것을 확인할 수 있다. 그 이후는 인식하지 않는다.

 

" Hazbin hotel " 이라면 "Hazbin" 이라고 인식하는 것이다.

 

 

 let movietitle = doc['name'].replace(' ','-')

 

그래서 데이터를 불러온 값에 변수 지정을 할 때 데이터를 불러올 때 문자 배열의 ' ' (띄어쓰기) 부분을 ' - ' (하이픈) 으로 바꿔!

 

라고 코드를 짠것이다. 김래준 매니저님은 천재가 아닐까,, 같이 머리를 싸매며 수십분은 고민을 하다 천재적인 발상을 해내셨다.

 

아무튼, 데이터 변수 할당에 replace 를 적용시킨다면,

 

 

 

내가 중복되는 값을 어떻게 처리해라 라고 명령을 내리지 않았으니 얼타고 있던 The, The ID 들은 이제 없다.

 

 검색 했을 시 선택받은 자 녀석도 이제는 노출되지 않는다.

 

요약 = ID 값은 띄어쓰기 전까지만 인식한다.

불러온 데이터의 문자열에 띄어쓰기를 하이픈으로 바꾼다면 해결할수 있다.

 

const options = {
  method: 'GET',
  headers: {
    accept: 'application/json',
    Authorization: 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI3MjI3NzE0MDM1MzEzNjBiZWU2YmRiNmIwZDUwOGVmMiIsInN1YiI6IjY2Mjc1ZTJiNjNkOTM3MDE4Nzc1NjUyZSIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.qGlRoILTnebygsMdUJdB_cYmdPsxI-EhBB49Aaja0Pg'
  }
};

  .then(response => response.json())
  .then(response => {                           // fetch 불러온거 (API)              
    let movie_list = response.results; // 불러온 데이터를 변수에 할당해준다
    let temp_html = ``; // temp_html 을 아무런 값도 없이 초기화 한다
    movie_list.forEach(doc => {          // 데이터 불러온걸 순회해서 변수들에 넣어준다
      let movietitle = doc['name'].replace(' ','-');  // raplace (' ' , '-') id 의 띄어쓰기는 읽지 않음, 그래서 id 의 띄어쓰기를 - (하이픈) 으로 바꾸면 되지 않을까~ 해서 replace 를 사용했음
      //The Attack of Titan -> The-Attack-of-Titan
      let overview = doc['overview']; //데이터에 변수 지정
      let image = 'https://image.tmdb.org/t/p/w500' + doc['poster_path']; //데이터에 변수 지정
      let vote_average = doc['vote_average']; //데이터에 변수 지정
      let card_id = doc['id']; // 데이터에 변수 지정


      // temp_html 의 += 카드 여러개 만든다는 뜻

      // html 요소를 만들어서 각 요소에 데이터를 넣는다.
      temp_html += `
   
     
        <li class="item" id=${movietitle} movie-id="${card_id}">
          <img src=${image} class="card-image">
          <div class="cont">
            <strong class="card-title">${movietitle}</strong>
            <p >${overview}</p>
            <p style="color: chartreuse;">grade : ${vote_average}</p>
          </div>
        </li>

        `;

        // fetch 로 데이터를 가져오면서 계속 변경되는 "item" 의 id 값을 ${movietitle} 로 지정해 데이터를 받아온다.

      document.getElementById('list_wrap').innerHTML = temp_html;

      // 얘가 있어야 적용이 됨, 다큐먼트에 id 값 list_wrap 안에 우리가 만든 temp_html 요소를 넣어준다.
      // document = html 전부
      // innerHTML = 채워준다

    })
    // el = 데이터를 표현하기 위한 언어
    // id 가 itemcard 인 모든걸 가져온다

    // queryselectorAll = document 에서 id 가 itemcard 인 애들을 싹 다 가져온다.
    // 가져와서 forEach 해준다

    document.querySelectorAll('.item').forEach((el) => {
      el.onclick = function () {

        let x = el.getAttribute("movie-id");  // getAttribute 요소의 속성을 가지고온다.

        alert('영화 ID :' + x);

      }   // 익명함수 , querySelectorAll , getAttribute

    })

  })

  // DOMContentLoaded 이벤트는 HTML 문서가 완전히 구문 분석되고 모든 지연된 스크립트가 다운로드되고 실행될 때 발생

document.addEventListener('DOMContentLoaded', () => {
  const payrollSearch = document.querySelector('#search-input');
  // input 박스를 querySelector를 사용하여 지정하고 payrollSearch에 저장

  function search() {

    // 카드 제목이 포함된 element를 class 값(.item)으로 가져와서 -> familyTitle
    const familyTitle = document.querySelectorAll('.item');
    // 입력한 검색어의 value값을 가져와 소문자로 변경하여 -> filterValue
    const filterValue = payrollSearch.value.toLowerCase();

    //console.log("검색어", filterValue)


    // familyTitle 안에 있는 문자열을 familyTitle 의 길이만큼 for문으로 순회
    for (let i = 0; i < familyTitle.length; i++) {
      // 순회하고 있는 familyTitle 의 textContent 를 소문자로 변경 -> rows
      let rows = familyTitle[i].textContent.toLowerCase();

      //console.log('이거!', payrollTitle[i].parentElement.parentElement)
     

      // 검색된 familyTitle 에 해당하는 카드의 id 값의 속성을 가져와 -> id
      const id = familyTitle[i].getAttribute('id');

     
      //rows가 filterValue를 포함하면 해당 title은 보여지게 하고, 그렇지 않으면 숨김
      // getElementById를 사용하여 id에 해당하는 카드를 가져온 후
      // style.display로 block(보여주기(=빈칸)) 할지 none(숨기기) 할지

      if (rows.includes(filterValue)) {

         document.getElementById(id).style.display = 'block';
         
      } else {

        document.getElementById(id).style.display = 'none';

      }
    }
  }
  //querySelector로 검색버튼(#search-button)을 지정하고 click 이벤트로 search 함수 실행
  document.querySelector('#search-button').addEventListener('click', search);

JS 코드

 

아직 한 참 부족하다. 문제점도 많을거고, 불필요한 구절도 있을 것이다.그래도 일단은 피드백을 받기 위한 준비는 끝난 것 같고, 내 코드에 대해 설명할 수 있는 힘을 기르면 될 것 같다.이 코드가 왜 쓰여졌고, 왜 이 코드를 쓸 수 밖에 없었냐 = 하는 질문에 대답을 하기가 애매하달까?

 

아직 JS 문법에 익숙치 않아서도 있겠지만, 코드 짜는 데 시간도 오래 걸렸고, 알고 있는 정보들

코드를 술 술 짜는 게 아닌 짜면서 필요한걸 검색하면서 짠 느낌이라 그런 것 같기도 하다.

 

그래도 뭐가 필요하고 어떤 식으로 로직을 짜야할지 정도는 아주 조금? 감이 잡힌 느낌?

 

변태같은 성향일지 모르겠지만 벽에 부딪혔을 때 이렇게 하면 안 될까? 이게 왜 안 되지? 하면서 콘솔 창도 확인하고콘솔창에 뜬 오류를 따라가면서 해결해나가는 과정이 너무 재밌는 것 같다. 게임 하는 느낌?

 

하다가 너무 안 되면 튜터님들을 찾아가서 시간 소모를 줄여야 하나? 싶기도 한데 오히려 이렇게 스스로 문제를 찾고 해결 해나가는 시간이 날 성장시키는 시간인 듯 싶다. 뭐, 사람마다 다른거니까.

( 해결 안 되면 당연히 찾아갈거임)