-
Day17. MovieAppUDEMY/50 Projects In 50 Days - HTML, CSS & JS 2024. 1. 12. 12:57728x90반응형SMALL
HTML
<header><form id="form"><input type="text" id="search" class="search" placeholder="Search"></form></header><main id="main"></main>CSS
.movie {width: 300px;margin: 1rem;background-color: var(--secondary-color);box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2);position: relative;overflow: hidden;border-radius: 3px;}position:relative;
relative: the element is positioned relative to its normal position.We can move relative element using top,bottom,left and right.
.movie-info span.green{color: lightgreen;}.movie-info span.orange{color: orange;}.movie-info span.red{color: red;}.overview{background-color: #fff;padding: 2rem;position: absolute;top: 0;bottom: 0;right: 0;max-height: 100%;transform: translateY(101%);transition: transform 0.3s ease-in;}position:absolute;
absolute: the element is positioned absolutely to its first positioned parent.
.overview to .movie
We can moved element and provide z-index. For example we position parent relative and move child using absolute property.
부모를 기준으로 이동.
부모 중 position이 relative, fixed, absolute 하나라도 있으면 그 부모를 기준으로 절대적으로 움직인다.
absolute를 쓸 경우, 기준이 될 부모에게 position: relative; 를 부여하고 원하는 위치를 지정하면 됩니다.
- translate : 현재위치를 기준으로 이동하기
- translateY() => 세로로 이동 (+값 아래쪽 -값 위쪽)
max-height: 100%;transform: translateY(101%);transition: transform 0.3s ease-in;최대 높이를 부모를 기준으로 100%
Y축의 101%에 이동. Y축의 1이 가장 위 100이 가장 아래. 즉, 가장 아래보다 밑에 위치
transition을 통해 0.3sec 천천히
.movie:hover .overview{transform: translateY(0);}hover 할 경우 .overview 클래스를 적용
Y축 101% to 0%
Y 축은 🔝↓ 상하 위에서 아래로
X 축은 ⇥⇤ 좌우 그럼 x 축은!?
JS
const API_URL =const main = document.getElementById('main');const form = document.getElementById('form');const search = document.getElementById('search');///get initial moviesgetMovies(API_URL);Movie API 주소를 API_URL 변수에 저장
MOVE API 내의 img를 IMG_PATH 변수에 저장
main 클래스를 main 변수에 저장
form 클래스를 form 변수에 저장
search 클래스를 search 변수에 저장
getMovies(API_URL)을 가장 먼저 업데이트
async function getMovies(url) {const res = await fetch(url);const data = await res.json();
showMovies(data.results);console.log(data.results);}async function getMovies(url)
비동기적으로 영화 데이터를 가져오기위해 async/await 사용
비동기 작업이란 특정 코드의 로직이 끝날 때까지 기다리지 않고, 나머지 코드를 먼저 실행하는 것.
빠른 페이지 로딩을 위해 웹사이트 개발에 비동기 작업이 사용.
기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완하고 개발자가 읽기 좋은 코드를 작성할 수 있게 도와준다.
특히, 복잡했던 Promise를 조금 더 편하게 사용할 수 있다.
function showMovies(movies) {
main.innerHTML = '';
movies.forEach((movie) => {const { title, poster_path, vote_average, overview } = movie;
const movieEl = document.createElement('div');
movieEl.classList.add('movie');
movieEl.innerHTML = `<img src="${IMG_PATH + poster_path}" alt="${title}"><div class="movie-info"><h3>${title}</h3><span class="${getClassByRate(vote_average)}">${vote_average}</span></div><div class="overview"><h3>Overview</h3>${overview}</div>`;main.appendChild(movieEl);});}API로 부터 영화 데이터를 받아와 HTML을 생성하여 화면에 표시하는 역할을 하는 두개의 함수 'showMovies'와 'getClassByRate'
를 정의.
showMovies 함수는 영화 데이터를 받아와 해당 데이터를 화면에 표시.
main.innerHTML = '';
초기화 가장 먼저 진행, 기존의 내용 삭제
movies.forEach((movie) => {const { title, poster_path, vote_average, overview } = movie전달받은 데이터 배열을 iteration 하여 각 영화에 대한 HTML 요소 생성{ "adult": false, "backdrop_path": "/vdpE5pjJVql5aD6pnzRqlFmgxXf.jpg", "genre_ids": [ 18, 36 ], "id": 906126, "original_language": "es", "original_title": "La sociedad de la nieve", "overview": "On October 13, 1972, Uruguayan Air Force Flight 571, chartered to take a rugby team to Chile, crashes into a glacier in the heart of the Andes.", "popularity": 1412.999, "poster_path": "/2e853FDVSIso600RqAMunPxiZjq.jpg", "release_date": "2023-12-13", "title": "Society of the Snow", "video": false, "vote_average": 8.1, "vote_count": 570 },
JSON화 되어 있는 데이터 의 key 값 title, poster_path, vote_average, overview
const movieEl = document.createElement('div');
새로운 div element를 생성한다. (createElement)
movieEl.classList.add('movie');
새로 생성된 movieEl = 'div' element에 'movie' 클래스를 추가 (add)movieEl.innerHTML = `
<img src="${IMG_PATH + poster_path}" alt="${title}">
<div class="movie-info">
<h3>${title}</h3>
<span class="${getClassByRate(
vote_average
)}">${vote_average}</span></div>
<div class="overview">
<h3>Overview</h3>
${overview}
</div>
`;
새로 생성된 'div' element를 설정.
백틱을 사용해서
이미지(img src="" alt="">,
제목(<h3></h3>,
평점(<span></span>),
overview<div><h3></h3></div>
의 내용을 포함.
${}을 사용해서 변수명 불러오기main.appendChild(movieEl);
새로 생성된 'div' element를 'main'에 요소로 추가(appendChild)
function getClassByRate(vote) {if (vote >= 8) {return 'green';} else if (vote > 5) {return 'orange';} else {return 'red';}}getClassByRate는 평점에 따라 css 클래스를 반환.
vote가 8 이상이면 그린 vote가 5 이상이면 감귤 둘다 아니면 레드
form.addEventListener('submit', (e) => {e.preventDefault();
const searchTerm = search.value;
if (searchTerm && searchTerm !== '') {// 검색어를 사용하여 동적으로 URL을 생성const searchURL = `https://api.themoviedb.org/3/search/movie?query=${searchTerm}&api_key=ca40de407fa88f223a1b5812f78d49fe`;// 수정된 URL을 사용하여 영화 정보를 가져옴getMovies(searchURL);
search.value = '';} else {window.location.reload();}});}Search 기능 구현
submit 될 경우 event 기능 구현
e.preventDefault();
이벤트 발생시 브라우저의 고유한 행동을 prevent.
기본동작, 고유한 행동을 막음으로써 페이지가 새로고침 되는 등의 행위가 발생하지 않고 js로 원하는 동작을 수행할 수 있게 해준다.
const searchTerm = search.value;
search.value 검색어를 가져와서 searchTerm 변수에 저장
if (searchTerm && searchTerm !== ''){
}
searchTerm의 값이 있고 공백이 아니라면
검색어를 사용하여 동적으로 URL을 생성const searchURL = `https://api.themoviedb.org/3/search/movie?query=${searchTerm}&api_key=ca40de407fa88f223a1b5812f78d49fe`;수정된 URL을 사용하여 영화 정보를 가져온다.getMovies(searchURL);
getMovies 함수를 호출하고 해당 검색어로 영화 정보를 가져 온다.
search.value = '';
검색어 처리 후 검색어를 비워준다.
} else {window.location.reload();}초기 상태로 돌아가기폼이 제출되면 검색어를 사용하여 동적으로 URL을 생성하고 해당 URL을 이용하여 영화 정보를 가져온다.
getMoives에 parameter로 전달되어 showMovies 함수실행
LOGIC
movie API를 활용
js DOM을 활용해서 불러온 정보(이름, 평점, 사진, 요약)를 html에 삽입
search 기능 구현
검색시 화면 전환
새로운 창에 검색내용 적용
RECAP
DB와 연동
comment 기능 연동
영화 click시 새로운 창을 불러오거나 modal처럼 적용해볼 수 있을 것
평점 순으로 정렬 같은 정렬 기능 구현 해볼 것
검색시 사진이 존재하지 않는다면 존재하는 것만 불러온다!?
평점의 소수점 한자리 이하는 버리기
728x90반응형LIST'UDEMY > 50 Projects In 50 Days - HTML, CSS & JS' 카테고리의 다른 글
Day18. Background Slider (0) 2024.01.12 Day16. DrinkWater (0) 2024.01.12 Day15.IncrementingCounter (2) 2024.01.02 Day14. AnimatedNavigation (0) 2024.01.02 Day13. RandomChoicePicker (0) 2024.01.02