반응형
요약
영화 검색 기능에서 어떻게 보여줄 것인지에 대한 고민
고민한 내용
우리는 영화의 리스트, TV의 리스트, 인물들을 보여줄 기획을 했다. 그래서 검색하는데 각 페이지마다 검색을 하게 됐을 때 해당 내용에서 검색이 되는 방향으로 가는게 맞을지에 대해서 고민을 했다. 거기에 인물은 따로 header에 넣지 않게 되면서 애매하게 됐다.
생각한 해결 방법
검색 페이지를 별도로 따로 만드는 것으로 가기로 했다. 그래서 검색을 하게 되면 영화, TV, 인물 모두가 검색이 되면서 한 화면에 다 보여주는 것이다. 거기에 각 카드를 클릭시 해당 디테일 페이지로 넘어가게끔 작업했다.
이번 팀 프로젝트를 하면서 api를 다루지 않아서 오히려 검색 작업은 재미가 있었다.
1. API를 하나만 호출해서 해결
3가지를 보여주기 위해서 media와 검색 키워드로 페이지를 api url에 보낼 수 있게 했다.
그래서 화면에 영화일땐 movie, 드라마일땐 tv, 인물일땐 person을 넣고 데이터를 가져왔다.
const options = {
method: "GET",
headers: {
accept: "application/json",
Authorization:
"testKey"
}
};
const fetchSearchData = async (page, media) => {
const data = await fetch(
`https://api.themoviedb.org/3/search/${media}?query=${searchKeyword}&language=ko&page=${page}`,
options
)
.then((response) => response.json())
.catch((err) => console.error(err));
return data;
};
2. 상황에 맞는 카드 뿌려주기
영화 챕터와 각 각에 맞게끔 뿌려주고, 더 보기를 누르면 1페이지씩 보이게끔 작업했다.
const makeLists = async (pageNum = 1, media = "movie") => {
const dataMovie = await fetchSearchData(pageNum, media);
console.log(dataMovie);
const { results, page, total_pages, total_results} = dataMovie;
const cardList = document.querySelector(`.card-search-${media}`);
const cardListLength = document.querySelector(`.${media}-length`);
cardListLength.innerHTML = total_results;
if( results.length == 0 ) {
cardList.innerHTML = '검색 결과가 없습니다.'
return;
}
cardList.setAttribute("data-page", page);
cardList.innerHTML += results
.map((item, idx) => {
// 영화 객체의 제목, 이미지경로, 내용, 평점 property를 구조 분해 및 할당을 이용해 저장한다
let id = item.id;
let title = item.name;
let poster_path = item.poster_path;
if ( media == "movie" ) title = item.title;
else if ( media == "person" ) poster_path = item.profile_path;
return poster_path != null ?
`<li data-id=${id} data-media=${media}>
<p class="img"><img src="https://image.tmdb.org/t/p/w500${poster_path}" alt="${title}"/></p>
<h3 class="title">${title}</h3>
</li>`
: `<li data-id=${id} data-media=${media}>
<p class="img img-null">No Img</p>
<h3 class="title">${title}</h3>
</li>`;
})
.join("");
const cardMore = document.querySelector(`.search-more-${media}`);
cardMore.setAttribute("data-page", page);
cardMore.setAttribute("data-media", media);
if(page != total_pages) {
cardMore.innerHTML =
`<button type="button">+</button>
`
;
} else {
cardMore.innerHTML = '';
}
const cardMoreAll = document.querySelectorAll(".search-more");
for (const more of cardMoreAll) {
let getPage = more.getAttribute("data-page")
let getMedia = more.getAttribute("data-media")
more.onclick = () => onMoreClicked(getPage, getMedia);
}
for (const child of cardList.children) {
child.addEventListener("click", onCardClicked);
}
// 카드 클릭시 ID 를 보여주기 위한 이벤트 핸들러
function onCardClicked(e) {
const id = e.currentTarget.getAttribute("data-id");
const media = e.currentTarget.getAttribute("data-media");
const data = {
id: id,
media: media
};
if ( media == 'movie' ) {
window.location.href = "/detail.html"
sessionStorage.setItem("data", JSON.stringify(data));
}
else if ( media == 'tv' ) {
window.location.href = "/TV.html"
sessionStorage.setItem("data", JSON.stringify(data));
} else {
window.location.href = "/personDetail.html"
sessionStorage.setItem("actorId", JSON.stringify(Number(data.id)));
}
}
};
// 더보기 클릭시 다음 페이지 추가
function onMoreClicked(page, media) {
page++
makeLists(page, media);
}
window.addEventListener("load", function () {
makeLists(1, 'movie');
makeLists(1, 'tv');
makeLists(1, 'person');
});
결과 화면
회고
영화 리뷰기능에선 데이터를 페이지별로 가져오지 않아서 원하는만큼 보여주고 더보기 기능을 할 때, 스크립트가 굉장히 복잡해졌었는데, api로 가져오면서 더보기를 하게 되니 페이지별로 가져올 수 있어서 더 편했다.
개발을 하게 되면 백엔드에서 소스를 페이지별로 보내주는 코드 하나만으로도 정리가 쉬울 수 있겠단 생각이 들었다.
반응형
'TIL' 카테고리의 다른 글
[TIL][23.11.14] React 팬레터 앱 만들기 - 1 (0) | 2023.11.14 |
---|---|
[TIL][23.11.07] React로 To-do-list 만들기 (0) | 2023.11.07 |
[WIL][23.10.31] 영화 API를 활용한 팀프로젝트 회고 (1) | 2023.10.31 |
[TIL][23.10.27] 영화 리뷰 기능에서 더보기 기능에 대한 고민 (0) | 2023.10.27 |
[TIL][23.10.26] 영화 리뷰 기능에서 시간 설정에 대한 고민 (0) | 2023.10.26 |