2023. 1. 6. 18:42ㆍ기록/Projects
- 목차
배포 링크 : movielly
원본 저장소 : 깃허브
팝.콘.이.내.린.다.
샤라라라라라라 ~~~~~ 🐱
OMDB API 를 활용하여
영화 검색 사이트를 만들어 보았다!
(데이터가 영어로 되어있어서 영어로 검색해야함)
처음에는 팝콘 애니메이션은 없었는데,
고양이 옆에 팝콘이 달랑 있는게 심심해보여서
추가하게 되었다..🍿🍿🍿🍿🍿
또한 처음으로 모듈화를 하여 구현하였다!
- getMovieData.js : 영화 데이터를 가져옴
- initElement.js : 엘리먼트 초기화 시 사용하는 함수들
- main.js : 라우팅, 초기화
- renderDetail.js : 영화 상세 렌더링
- renderMovies.js : 영화 목록 렌더링
- renderSearch.js : 검색 영역 렌더링
- setElement.js : 엘리먼트 조작/셋팅
SPA 구현
const routes = [
{ path: 'search', component: renderSearch },
{ path: 'detail', component: renderDetail },
{ path: 'likes', component: renderLikes },
];
window.addEventListener('hashchange', () => {
const hash = window.location.hash.replace('#', '').split('/')[0];
let component = '';
routes.forEach((route) => {
if (route.path === hash) {
component = route.component;
document.querySelector(`.nav-${route.path}`).classList.add('active');
} else {
document.querySelector(`.nav-${route.path}`).classList.remove('active');
}
});
component();
});
해쉬를 이용하여 SPA를 구현해 보았다.
미리 라우터 객체를 정의해둔 후에
해쉬 값이 변경되면 라우터 객체에서 해당 해쉬값을 key로하여 값을 찾고
그 값인 렌더링 함수를 찾아 호출한다!
영화 검색
3글자 부터 검색이 가능하다.
검색 결과가 없을 경우 목록 영역을 숨기고 말풍선을 보여준다.
검색 결과가 있을 경우 목록 영역으로 자동으로 이동하여 보여준다.
무한 스크롤을 적용하여 스크롤을 내리면
검색 결과가 존재할 때까지 새로운 데이터를 무한으로 보여준다!
(IntersectionObserver 사용)
const infinityScroll = () => {
let scrollLoading = document.querySelector('.scroll-loading');
if (!scrollLoading) {
scrollLoading = document.createElement('div');
scrollLoading.className = 'scroll-loading';
for (let i = 0; i < 3; i++) {
const span = document.createElement('span');
scrollLoading.append(span);
}
document.querySelector('main').append(scrollLoading);
}
const option = {
threshold: 1,
};
const callback = (entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
if (document.querySelector('.movie')) {
renderScrollMovies();
}
observer.observe(scrollLoading);
}
});
};
const observer = new IntersectionObserver(callback, option);
observer.observe(scrollLoading);
};
export const getScrollMovies = async () => {
const search = document.querySelector('.search-input').value;
const type = document.querySelector('.type').value;
const year = document.querySelector('.year').value;
const page = ++curPage;
const res = await fetch(`${API_URL}?apikey=${API_KEY}&s=${search}&type=${type}&y=${year}&page=${page}`);
const { Search: movies } = await res.json();
return movies;
};
최근 본 영화 상세 목록
영화 목록에서 영화 선택 시 상세 페이지를 보여준다.
Recent 목록에서 최근 본 영화 상세 목록을 확인할 수 있다.
localStorage 를 이용해 구현하였다!
상세 페이지를 보여줄 때 localStorage 에 해당 영화 ID가 있는지 판별한다.
최근 순으로 정렬되어 있어야 하기 때문에 로직을 추가해 주었다.
- recents 배열의 가장 마지막에 해당 영화 ID가 있을 경우 ID를 넣어주지 않는다.
- recents 배열에 해당 영화 ID가 있을 경우 ID를 삭제하고 다시 넣어준다.
- recents 배열에 해당 영화 ID가 없을 경우 ID를 넣어준다.
const setRecentsStorage = (movieId = DEFAULT_ID) => {
const recents = JSON.parse(localStorage.getItem('recents'));
if (recents[recents.length - 1] !== movieId) {
if (recents.includes(movieId)) {
setStorage('recents', movieId, 'delete');
setStorage('recents', movieId, 'insert');
} else {
setStorage('recents', movieId, 'insert');
}
}
};
좋아요 한 영화 목록
하트 아이콘을 클릭하면 좋아요 한 영화 목록에 추가된다.
마찬가지로 localStorage 를 이용해 구현하였다.
빨간 하트를 다시 클릭 시 좋아요 한 영화 목록에서 삭제된다.
document.querySelector('.like-btn').addEventListener('click', () => {
if (!likes.includes(imdbID)) {
setStorage('likes', imdbID, 'insert');
spanEl.classList.add('like');
} else {
setStorage('likes', imdbID, 'delete');
spanEl.classList.remove('like');
}
});
처음으로 자바스크립트로 모듈화를 하여 코드를 작성해 보았는데,
import, export 를 이용해 필요한 부분을 재사용할 수 있어서 좋았다!
앞으로도 모듈화를 할 수 있는 부분은
모두 모듈화를 해서 코드를 짜보아야겠다!!! 🐱👍