[JS 개인과제] 영화검색하기_검색기능 / 카드 클릭시 Alert 띄우기

Habin Lee·2023년 10월 20일
2

영화 검색하기 과제 미리보기

JS 완성코드

<body>
    <div class="mytitle">
        <h1>Best Movie Collection</h1>
    </div>
    <div class="mysearch">
        <h2>Search Movie :</h2>
        <div>
            <div class="center">
                <input type="text" class="searchframe" id="search-box" placeholder="영화 제목을 검색해 주세요" />
            </div>
        </div>
        <button class="btn" id="SearchBtn">Search</button>
    </div>
</body>

<script>
        fetch('https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1', options)
            .then(response => response.json())
            .then((data) => {
                console.log(data)
                data.results.forEach(element => {
                    document.querySelector('.row').innerHTML += `
                        <div class="movie-card" id="${element.id}"token interpolation">${element.id}')">
                <div class="card">
                    <img src=${`https://image.tmdb.org/t/p/w400` + element.backdrop_path} class="card-img-top" art="...">
                    <div class="card-body">
                        <h4 class="card-title" id="card-title">${element.original_title}</h4>
                        <p class="card-text">${element.overview}</p>
                        <p class="card-text"><small class="text-body-secondary">${`Rating : ` + element.vote_average}</small></p>
                    </div>
                </div>
            </div>
                    `;
                })
            })
            .catch(err => console.error(err));

        document.addEventListener('DOMContentLoaded', () => {
            const payrollSearch = document.querySelector('#search-box');     

            function search() {
                const payrollTitle = document.querySelectorAll('.card-title');
                
                const filterValue = payrollSearch.value.toLowerCase();

                for (let i = 0; i < payrollTitle.length; i++) {
                   
                    let rows = payrollTitle[i].textContent.toLowerCase();

                    const id = payrollTitle[i].parentElement.parentElement.parentElement.id;

                    if (rows.includes(filterValue)) {
                        document.getElementById(id).style.display = '';
                    } else {
                        document.getElementById(id).style.display = 'none';
                    }
                }
            }
            document.querySelector('#SearchBtn').addEventListener('click',search);
        })
</script>

문제점과 해결방법

1. 카드 전체를 지칭하는 이름이 헷갈린 문제

만들어지는 card-body의 이름을 col로 지정해놔서 정작 내가 알아보지 못해 생긴 문제였다.. 나중에라도 코드를 다시 봤을때 헷갈리지 않기 위해 movie-card로 바꾸니 훨씬 직관적이고 보기가 좋아져 해당 카드에 해당하는 코드를 찾기가 쉬워졌다. 개발자는 코드를 작성하면서 이름을 잘 지으려는 습관(버릇)이 있다고 들었는데 왜 생겼는지 알 것 같다.

2. 영화카드를 눌렀을 때 ID값이 Alert되지 않는 문제

처음에는 document.querySelector 나 document.getElementById 를 사용하여 코드를 짰는데, 아무리 해도 alert가 되지 않아서 팀원에게 도움을 요청했다.
둘 다 이미 생성되어 있는 개체를 지정하는 것은 가능하지만 지금처럼 API값을 불러와서 카드가 생성되는 경우에는 document가 먼저 실행되고 API값을 불러오기 때문에 null 값이 나와 카드가 클릭이 되지 않는 문제였다.
그래서 생성되는 movie-card에 직접 onclick을 먹여주고 바로 alert을 지정했더니 클릭과 알림이 제대로 작동을 했는데, 생각보다 간단하게 해결을 해서 조금 신기했다.
생성되는 카드를 지칭하는 백틱 안에서 코드를 작성하려니 부호가 많이 헷갈렸는데, 이 부분도 자주 적어보고 익숙해져야겠다.

3. 검색이 안되는 문제

내용이 너무 길어 코드 안에서 주석처리 설명

// fetch로 계속 변경되는 movie-card 의 id를 ${element.id}로 데이터를 먼저 받아온다.
<div class="movie-card" id="${element.id}" onclick="alert('영화 ID: ${element.id}')">
  
// DOMContentLoaded 이벤트는 HTML 문서가 완전히 구문 분석되고 모든 지연된 스크립트가 다운로드되고 실행될 때 발생
document.addEventListener('DOMContentLoaded', () => {
  			// input 박스를 querySelector를 사용하여 지정하고 payrollSearch에 저장
            const payrollSearch = document.querySelector('#search-box');     
			// search 함수
            function search() {
                // 카드 제목 element를 id 값(card-title)으로 가져오기
                const payrollTitle = document.querySelectorAll('.card-title');
                // 사용자가 입력한 검색어의 value값을 가져와 소문자로 변경하여 filterValue에 저장
                const filterValue = payrollSearch.value.toLowerCase();
                // payrollTitle, filterValue이 잘 나오는지 중간 점검
                console.log(payrollTitle);
                console.log(filterValue);

                // payrollTitle 안에 있는 문자열을 payrollTitle의 길이만큼 for문으로 순회
                for (let i = 0; i < payrollTitle.length; i++) {
                    // 현재 순회중인 payrollTitle의 textContent를 소문자로 변경하여 rows에 저장
                    let rows = payrollTitle[i].textContent.toLowerCase();
                    console.log(rows);
                  
                  // 아래의 변수명 id를 지정하기 위해 parentElement를 얼마나 붙여야하는지 점검
                  // => parentElement를 3번 사용하니 영화ID 값에 접근할 수 있었다.
                    if(i === 0) {
                        console.log(payrollTitle[i].parentElement)
                        console.log(payrollTitle[i].parentElement.parentElement)
                        console.log(payrollTitle[i].parentElement.parentElement.parentElement)
                        }

                    // 검색된 payrollTitle에 해당하는 카드의 id값을 부모태그로 선택해 id라는 변수명으로 저장
                    const id = payrollTitle[i].parentElement.parentElement.parentElement.id;
                    // rows가 filterValue를 포함하면 해당 title은 보여지게 하고, 그렇지 않으면 숨김
                    if (rows.includes(filterValue)) {
                        // getElementById를 사용하여 id에 해당하는 카드를 가져온 후
                        // style.display로 block(보여주기(=빈칸)) 할지 none(숨기기) 할지
                        document.getElementById(id).style.display = '';
                    } else {
                        document.getElementById(id).style.display = 'none';
                    }
                }
            }
            // querySelector로 검색버튼(SearchBtn)을 지정하고 click 이벤트로 search 함수 실행
            document.querySelector('#SearchBtn').addEventListener('click',search);
  
  			// 검색버튼을 누르지 않고 검색창에 입력하자마자 사용할 수 있는 keyup활용 가능
            // payrollSearch.addEventListener('keyup', search);
        })

문제점은 아니지만 추가 CSS

1. 카드에 커서를 올렸을때 눈에 보이는 변화만들기

영화 카드를 누르면 alert 되는 것까지는 해결을 했는데, 문제는 카드에 마우스를 올려도 우리가 흔히 아는 손가락 모양이 나타나지 않아서 당황했었다. 그냥 되는건줄 알았는데 하나하나 지정해서 해줘야한다는게 신기했다. 아무것도 모를 때는 그냥 사용했지만 알고 나니 개발을 할 때 생각보다 굉장히 디테일하게 해줘야한다는 것을 알게 됐다.

        .movie-card {
            cursor: pointer;
            scale: 1;
            transition: scale 0.3s ease;
        }

        .movie-card:hover {
            scale: 1.02;
        }

카드 전체에 cursor를 pointer로 지정해 마우스 모양을 손모양으로 바꿔줬는데, 뭔가 심심해서 팀원의 도움을 받아 카드 자체가 변화가 있도록 변경해줬다.

  1. 카드에 마우스를 올리면(movie-card:hover)
  2. 기본 1로 잡아준 scale 값(movie-card의 scale: 1;)을
  3. 1.02로 변경(movie-card:hover의 scale: 1.02;)하고
  4. transition에 scale이 0.3초 후에 부드럽게(ease) 바뀔 수 있도록 코드를 추가해준다.

scale은 값이 너무 크면 카드가 엄청 크게 바뀌므로 조금씩 늘려주도록 하자.

오늘 느낀점

사실 개인 과제를 처음 시작할 때는 막막했는데, 강의영상과 구글링, 특히 팀원들의 도움을 받아 완성하고 나니 뿌듯하고 자신감이 조금 퐁퐁 솟아났다.
모르는 것을 하나하나 알아갈 때마다 쬐끔씩 앞으로 나아가는 것 같아서 뭔가 하고 있는 기분이 든다!

0개의 댓글