๋๋์ด ์ฒซ๋ฒ์งธ ๊ณผ์ ๋ฅผ ๋ฐ๊ฒ ๋์๋ค. ์ธ๊ณ์ ์ธ ์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ธ TMDB์ API๋ฅผ ์ฌ์ฉํด์,ย ์ง์ง ์ํ ๊ฒ์ ์ฌ์ดํธ๋ฅผ ๋ง๋ค์ด๋ณด๋ ๊ฒ!๋๋ํ์ ์ผ๋ก ๊ตฌํ๋์ด์ผ ํ ๊ธฐ๋ฅ์ ๊ฒ์, ๋ชจ๋ฌ, ๋ถ๋งํฌ ๊ธฐ๋ฅ์ด์๋ค.
์ด๋ฒ ํ๋ก์ ํธ์ ๋ชฉํ๋
์ผ๋จ ๋๋ [์ง์ค๋ฐ]์ด์๊ธฐ๋๋ฌธ์ ๋ถ๋งํฌ๋ฅผ ๊ตฌํํ์ง ์์๋ ๋์ง๋ง,
์๋๋ ํด๋ณธ ์ข์ ํ๋ก์ ํธ ์๋ค. ์ผ๋จ ์งํ๊ณผ์ ์ ๋ณด์ฌ์ฃผ์๋ฉด
const movieContainer = document.getElementById("movie-container");
let allMovies = [];
async function getMovieData() {
const url = `https://api.themoviedb.org/3/movie/popular?api_key=${TMDB_API_KEY}&language=ko-KR&page=1`;
try {
const response = await fetch(url, {
method: "GET",
headers: {
accept: "application/json",
Authorization: `Bearer ${TMDB_API_KEY}`,
},
});
const data = await response.json();
allMovies = data.results;
displayMovies(allMovies);
return data;
} catch (error) {
console.error("Error fetching movie data:", error);
}
}
์ผ๋จ TMDB์ API๋ฅผ ๊ฐ์ ธ์ค๋๊ฒ ์ฐ์ ์ด์๋๋ฐ
๋๋ API๋ฅผ ์ฒ์ ๊ฐ์ ธ์๋ณด๋ ์
์ฅ์ด๋ผ ๋ชจ๋ ๊ฒ ๊ฒ์ ๊ฒ์์ด์๋ค!
ํ์ ๊ฐ์
์ ํ๊ณ , ์ฌ์ดํธ์์ ์คํ API key๋ฅผ ๋ฐ์์๋ค.
๊ฐ์ฅ ๋จผ์ async
๋ฅผ ์ฌ์ฉํด์ ํจ์๊ฐ ๋น๋๊ธฐ์ ์ผ๋ก ๋์ํ๊ฒ ๋ง๋ค์ด์คฌ๋ค. ๊ทธ๋ ๊ฒ ๋๋ฉด API ํธ์ถ๊ณผ ๊ฐ์ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ์์
์ ์ฒ๋ฆฌํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ TMDB API์ ์๋ํฌ์ธํธ URL์ ์ค์ ์ ํด์ฃผ๊ณ ์ธ์ด๋ ํ๊ตญ์ด, ์ฒซ๋ฒ์งธ ํ์ด์ง ๊ฒฐ๊ณผ๋ฅผ ์์ฒญํ๋ค.fetch
๋ฅผ ์ฌ์ฉํ์ฌ API์ GET ์์ฒญ
์ ๋ณด๋
๋๋ค ์ธ์ฆ์ ์ํ ํค๋๋ฅผ ํฌํจ์ํจ๋ค. await
๋ ์๋ต์ ๋ฐ์ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค.์๋ต์ JSON
ํํ๋ก ๋ณํํ๊ณ ! ๊ฒฐ๊ณผ๋ฅผ allMovies ๋ฐฐ์ด๋ก ์ ์ฅํ๋ค.displayMovies
ํจ์๋ฅผ ํธ์ถํ์ฌ ์ํ ๋ชฉ๋ก์ ํ๋ฉด์ ํ์ํ๋ค. ๊ทธ๋ฆฌ๊ณ catch
๋ก API ํธ์ถ ์ค ๋ฐ์ํ ์ ์๋ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ค.
function displayMovies(movies) {
movieContainer.innerHTML = "";
movies.forEach((movie) => {
const movieElement = document.createElement("div");
movieElement.classList.add("movie");
movieElement.setAttribute("data-movie-id", movie.id);
movieElement.innerHTML = `
<div id="card">
<img src="https://image.tmdb.org/t/p/w500${
movie.poster_path
}" alt="${movie.title}" class="movie-poster">
<h3 class="movie-title">${movie.title}</h3>
<p class="movie-rating">โญ ${parseInt(movie.vote_average).toFixed(
1
)} / 10</p>
</div>
`;
movieContainer.appendChild(movieElement);
});
}
getMovieData();
๊ทธ๋ฆฌ๊ณ ์ํ๋ค์ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋ ํจ์๋ฅผ ๋ง๋ค์๋ค. ์ผ๋จ ๊ฑท๊ธฐ๋ฐ์์ ๋ฐฐ์ด๋๋ก movieContainer.innerHTML = "";
๋น html์ ์ฃผ๊ณ (๋ฐ์ดํฐ๊ฐ ์ค๋ณต ํ์๋๋๊ฑธ ๋ง๊ธฐ์ํด!) ๋ฐฐ์ด์ ๊ฐ ์ํ ๊ฐ์ฒด์ ๋ฐ๋ณต ์์
์ forEach
๋ก ์ฃผ์๋ค.const movieElement = document.createElement("div");
๋ก ๊ฐ ์ํ๋ฅผ ์ํ ์๋ก์ด div๋ฅผ ์์ฑํ๋ค. "movie"ํด๋์ฌ๋ฅด ์ถ๊ฐํ๊ณ ์ํ์ ๊ณ ์ ID๋ฅผ ๋ฐ์ดํฐ ์์ฑ์ ์ ์ฅํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ํ ์นด๋์ ๊ตฌ์กฐ๋ ์ํ ์ด๋ฏธ์ง, ์ํ ์ ๋ชฉ, ์ํ ํ์ ์ด ๋ํ๋ ์ ์๊ฒ ํ๋ค. ์ฌ๊ธฐ์์ ํ์ ์ด ์์์ 4์๋ฆฌ๊น์ง ๋์ค๋ ๊ตฌ์กฐ์ฌ์ toFixed(1)
๋ก ํ์๋ฆฌ์๋ง ๋์ค๊ฒ ๋ง๋ค์ด ์ฃผ์๋ค. ์ด์ ์ด ๋ง๋ ์ํ ์นด๋๋ค์ movieContainer.appendChild(movieElement);
์ถ๊ฐํด์ฃผ๊ณ ํจ์๋ฅผ ํธ์ถํด์ค๋ค.
โโโโโโโโโโโ
โ [ํฌ์คํฐ] โ
โ โ
โ ์ํ ์ ๋ชฉ โ
โ โญ ํ์ /10 โ
โโโโโโโโโโโ
์ด๋ฐ ๊ตฌ์กฐ์ ์ํ ์นด๋๊ฐ ๋ง๋ค์ด์ง๋ค !!!! ๐
๊ฒ์ ๊ธฐ๋ฅ ๊ตฌํ์ ์กฐ๊ฑด์ด ์์๋ค ๋ฐ๋ก ์๋์ฒ๋ผ !
// ๊ฒ์ ํผ๊ณผ ๊ฒ์ ์
๋ ฅ์ฐฝ ์์๋ฅผ ๊ฐ์ ธ์์ฃผ๊ณ ,
const searchForm = document.querySelector(".search-box");
const searchInput = document.querySelector(".search-txt");
//๊ฒ์ ํจ์๋ฅผ ์ ์ํด์ฃผ๊ณ API ํธ์ถ์ ํ๋ค -> ๊ทธ ๊ฒฐ๊ณผ ์ฒ๋ฆฌ๋ ์ด๋ ๊ฒ
fetch(url)
.then((response) => response.json())
.then((data) => {
//๊ฒ์ ๊ฒฐ๊ณผ์ ์กฐ๊ฑด์
if (data.results.length > 0) {
allMovies = data.results;
displayMovies(allMovies);
} else {
movieContainer.innerHTML = "<p>๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ด์ ใ
ใ
</p>";
}
//์๋ฌ๋ ๋ง์ฐฌ๊ฐ์น๋ก catch !
.catch((error) => {
console.log("์๋ฌ ๋ฐ์:", error);
movieContainer.innerHTML = "<p>์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋ค์ ์๋ํด ์ฃผ์ธ์!</p>";
});
๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ผ๋ฉด allMovies
๋ฐฐ์ด์ ์ ์ฅํ๊ณ displayMovies
ํจ์๋ฅผ ํธ์ถํด์ ํ๋ฉด์ ํ์ํ๋ค. ์๋ค๋ฉด ํ๋ฉด์ ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ด์ ใ
ใ
์ฌ๊ธฐ๊น์ง๋ ๊ทธ๋ฅ ์ ๋ฅ ๊ด์ฐฎ์๋ค. ๊ทธ๋ฐ๋ฐ ์ค์๊ฐ์ผ๋ก ์ํ ๊ฒ์์ด ๊ตฌํ๋๊ฒ ๋ง๋ค๊ณ ์ถ์๋ค
๋ง์น ใ
ํ๋์น๋ฉด ใ
์ด๋ค์ด๊ฐ ์ํ๋ค์ด ๋ฐ์ ๋ฐ๋ผ์ค๋ (>)
์ฌ๊ธฐ์๋ถํฐ ์ ๋ชฝ์ ์์์ด์์ง.............๐ฅ
searchInput.addEventListener("input", function() {
const searchTerm = searchInput.value.trim();
if (searchTerm) {
searchMovies(searchTerm);
} else {
getMovieData();
}
});
์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ input
์ผ๋ก ์ฃผ์ด์ ์ค์๊ฐ์ผ๋ก ์
๋ ฅ์ฐฝ์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๊ฒ ํ๋ค. ๊ทธ๋ฆฌ๊ณ trim()
์ผ๋ก ๊ณต๋ฐฑ๊น์ง ์ง์์ฃผ๊ณ searchMovies
ํจ์๋ฅผ ํธ์ถํด์ ๊ฒ์ํ๊ฒ ๋ง๋ค์๋ค.
ํ์ง๋ง ์ฌ๊ธฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. ๊ฒ์์ ๋๋๋ฐ ๊ฒ์์ฐฝ์ ๊ฒ์์ด๋ฅผ ๋น์๋ ์๋์ ํ๋ฉด์ผ๋ก ๋์๊ฐ์ง ์๋ ๋ค๋ ์ ,,,(ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
ใ
)
๊ทธ๋์ ๋ค์ else {getMovieData();}
๋ก ๊ฒ์์ด๊ฐ ๋น๋ฉด getMovieData
ํจ์๋ฅผ ํธ์ถํ๋ค ํด๊ฒฐ !!!!!!!!!!
์ด ๋ถ๋ถ์ ํ ์๊ฐ ๋ฏธ๋ ํ๋ก์ ํธ์์ ๋ชจ๋ฌ์ ํ ๋ฒ ๋ดค์๋ค. ๊ทธ๋์ ๋ชจ๋ฌ์ ์ฃผ๋ฉด ๋ ๊ฑฐ ๋ผ๋ ์๊ฐ์ ํ๊ณ ์์๋๋ฐ ๋ง์นจ ์กฐ๊ฑด๋ !
4. Day 4: ์ํ ์์ธ ํ์ด์ง ๊ตฌํ
- ๊ฐ ์ํ ์นด๋๋ฅผ ํด๋ฆญํ์ ๋, ์ํ์ย ์์ธ ์ ๋ณด(์: ์ค๊ฑฐ๋ฆฌ, ๊ฐ๋
, ๊ฐ๋ด์ผ ๋ฑ)๋ฅผ API์์ ์ถ๊ฐ๋ก ๋ฐ์์ ํ๋ฉด์ ํ์ํ์ธ์.
- ์์ธ ์ ๋ณด๋ย ์๋ก์ด ํ์ด์งย ๋๋ย ๋ชจ๋ฌ ์ฐฝ์ผ๋ก ๋ณด์ฌ์ฃผ๋ฉด ๋ฉ๋๋ค.
- ์ค์ ํฌ์ธํธ: ํด๋ฆญ๋ ์ํ์ย ID๋ฅผ ํ์ฉํ์ฌ TMDB API๋ก๋ถํฐ ํด๋น ์ํ์ ์์ธ ์ ๋ณด๋ฅผ ์์ฒญํด์ผ ํฉ๋๋ค.
```javascript
//์ผ๋จ ์์์ ๋ชจ๋ฌ๊ณผ ๊ด๋ จ๋ html ์์๋ค์ ์ ๋ถ ๋ณ์ ์ ์ธ ํด์ฃผ์๊ณ ,
function openModal(movie) {
modalPoster.src = https://image.tmdb.org/t/p/w500${movie.poster_path}
;
modalTitle.textContent = movie.title;
modalTitle.setAttribute("data-movie-id", movie.id);
modalOverview.textContent = movie.overview || "๊ฐ์ ์ ๋ณด๊ฐ ์์ต๋๋น";
modalRating.textContent = โญ ${movie.vote_average.toFixed(1)} / 10
;
modalReleaseDate.textContent = ๊ฐ๋ด์ผ: ${movie.release_date || "์ ๋ณด ์์"}
;
updateBookmarkButtons(movie.id);
}
movieContainer.addEventListener("click", (e) => {
const clickedCard = e.target.closest(".movie");
if (clickedCard) {
const clickedMovieId = parseInt(clickedCard.getAttribute("data-movie-id"));
const selectedMovie = allMovies.find(
(movie) => movie.id === clickedMovieId
);
if (selectedMovie) {
openModal(selectedMovie);
modal.style.display = "block";
}
}
});
์ํ ๊ฐ์ฒด๋ฅผ ๋ฐ์์ ๋ชจ๋ฌ ๋ด์ฉ์ ์ฑ์์คฌ๋ค. ์ ๋ณด๊ฐ ์๋ค๋ฉด ||์ฐ์ฐ์๋ฅผ ์ฌ์ฉํด์ ๋์ฒด ํ
์คํธ๊ฐ ๋์ฌ ์ ์๊ฒ ๋ง๋ค์ด ์คฌ๊ณ ๋ถ๋งํฌ ์ํ๋ ์
๋ฐ์ดํธ ํ ์ ์๊ฒ ํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ์์ ๋ด๊ฐ ๋ชจ๋ฅด๋ ๊ฐ๋
์ด ๋์ค๋๋ฐ ์ด๋ฒคํธ ์์์ด๋ผ๋ ๊ฐ๋
์ด๋ค.`const clickedCard = e.target.closest(".movie");` ์ด ๋ถ๋ถ์`closet๋ฉ์๋`๋ฅผ ์ฌ์ฉํด์ ํด๋ฆญ๋ ์์์ ๊ฐ์ฅ ๊ฐ๊น์ด `.movie`์์๋ฅผ ๊ฐ์ง ์กฐ์ ์์๋ฅผ ์ฐพ๊ฒ ํ๋ค.
ํด๋ฆญ ๋ ์ํ ์ ๋ณด ์นด๋๊ฐ ์กด์ฌํ๋ฉด data-movie-id๋ฅผ ๊ฐ์ ธ์จ๋ค!`parseInt()`๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด ID๋ฅผ ์ซ์๋ก ๋ณํํด์ฃผ์๋ค. `find()` ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ `allMovies` ๋ฐฐ์ด์์ ํด๋ฆญ๋ ์ํ๋ฅผ ์ฐพ์์ค๋ค. (ํ๋๋ง ์ฐพ์์ค์ผํ๋๊น !) ์ํ ID๋ฅผ ๊ธฐ์ค์ผ๋ก ๋งค์นญ๋๋ค.
๊ทธ๋ ๊ฒ ์ํ๋ฅผ ์ฐพ์ผ๋ฉด ? `openModal()` ํจ์๋ฅผ ํธ์ถ ===> ๋ชจ๋ฌ์ ํ๋ฉด์ ํ์ !๐
```javascript
const closeModal = () => {
modal.style.display = "none";
};
์ด๊ฒ๋ ๊ฑท๊ธฐ๋ฐ ์์ ์์ ๋ฐฐ์ด ๋ด์ฉ ๊ทธ๋๋ก ๋ชจ๋ฌ ๋ซ๋ ํจ์์ ์ ์ฉ์ ํด์ฃผ์๊ณ ,
modalCloseBtn.addEventListener("click", closeModal);
window.addEventListener("click", (event) => {
const modal = document.getElementById("movie-modal");
if (event.target === modal) {
closeModal();
}
});
๋ชจ๋ฌ์ ๋ซ๋ ๋ฐฉ๋ฒ์ ๋๋ ๋๊ฐ์ง๋ฅผ ๊ตฌํํ๋๋ฐ
์ด๋ ๊ฒ ํํ์ ํ๊ณ ๋๋๊น ๋ซ๊ธฐ ๋ฒํผ์ ๊ฐ์์ฑ๊ณผ ์๊ด์์ด ์ฌ์ฉ์๊ฐ ์๋ฌด๋ฐ๋ ํด๋ฆญํด๋ ๋ชจ๋ฌ์ด ๋ซํ์ ์ฌ์ฉ์ฑ์ด ํธ๋ฆฌ ํ ๊ฑฐ๋ผ๊ณ ํ๋จํ๋ค ๐คโ
let bookmarkPageState = false;
bookmarkReverseBtn.addEventListener("click", (e) => {
bookmarkPageState = false;
displayMovies(allMovies);
bookmarkBtn.style.display = "block";
bookmarkReverseBtn.style.display = "none";
});
์ฌ์ค ๋ถ๋งํฌ ๋ถ๋ถ ๋ถํฐ๋ ๋ค๋ฅธ๋ถ์ด๋ ๊ตฌ๊ธ๋ง์ ๋์์ ๋๋ฌด ์ ์คํ ๋ฐ์๋ค. ๋ถ๋งํฌ ์ญ์ ๋ฒํผ์ ๋๋ฅด๊ฒ๋๋ฉด bookmarkPageState = false;
๋ฅผ ๋ง๋ค์ด์ค๋ค. ์ ์ฒด ์ํ ๋ณผ ์ ์๊ฒ !
๊ทธ๋ฆฌ๊ณ displayMovies(allMovies);
๋ก allmovies์ ์๋ ์ํ ๋ชฉ๋ก์ ๋ค์ ํ์ํ๊ฒ ํด์คฌ๋ค. ๊ทธ ๋ค์ ๋ฒํผ์ ๋ค์ ๋ถ๋งํฌ ์ญ์ ๋ฒํผ์ ๊ฐ์ถ๊ณ ์ถ๊ฐ ๋ฒํผ์ด ๋ณด์ผ ์ ์๊ฒ ํด์ฃผ์๋ค.
์ฌ์ค ๋ชจ๋ํ๊ฐ ์ ํํ ๋ฌด์ง ๋๋ ๋๋ฌด ์ด๋ ต๊ณ ์ฝ๋๋ ๋ถ๋ฆฌ๋ฅผ ์ต๋ํ ํด์คฌ๋ค.
๋ชจ๋ฌ, ๊ฒ์, api, ๋ถ๋งํฌ js ๋ฅผ ๋ฐ๋ก ํด์ฃผ์๊ณ , css๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฐ๋ก ๋ถ๋ฆฌํด์ ์์ฑํ๋ค.
๋๋ฒ๊น
์ด ์ ํํ ๋ญ์ง ์ดํดํ๊ธฐ ์ด๋ ค์ ์ง๋ง ์ฝ์์ฐฝ์ ๋ด๊ฐ ๊ฐ์ ธ์จ ์ํ๋ค์ ๋ชฉ๋ก์ด ๋จ๊ณ ,
์๋ฌ๊ฐ ๋๋ ๋ถ๋ถ๋ ์์๋ค.
๊ทธ๋์ ์ต์ข ๊ตฌํ ํ๋ฉด์ ๋ณด์ฌ์ฃผ์๋ฉด,
๐๊ฐ์ธ๊ณผ์ ๋ฅผ ์งํํ๋ฉด์ ์์ฌ์ ๋ ์
๐๊ฐ์ธ ๊ณผ์ ๋ฅผ ์งํํ๋ฉด์ ์ํ๋ค๊ณ ์๊ฐํ ์