๐ŸŽฅ์ฒซ๋ฒˆ์งธ ๊ฐœ์ธ ๊ณผ์ œ - ์˜ํ™” ์†Œ๊ฐœ ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

์กฐ์•„๋ผยท2024๋…„ 10์›” 23์ผ
1
post-thumbnail

๋“œ๋””์–ด ์ฒซ๋ฒˆ์งธ ๊ณผ์ œ๋ฅผ ๋ฐ›๊ฒŒ ๋˜์—ˆ๋‹ค. ์„ธ๊ณ„์ ์ธ ์˜ํ™” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ธ TMDB์˜ API๋ฅผ ์‚ฌ์šฉํ•ด์„œ,ย ์ง„์งœ ์˜ํ™” ๊ฒ€์ƒ‰ ์‚ฌ์ดํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋Š” ๊ฒƒ!๋Œ€๋Œ€ํ‘œ์ ์œผ๋กœ ๊ตฌํ˜„๋˜์–ด์•ผ ํ•  ๊ธฐ๋Šฅ์€ ๊ฒ€์ƒ‰, ๋ชจ๋‹ฌ, ๋ถ๋งˆํฌ ๊ธฐ๋Šฅ์ด์—ˆ๋‹ค.

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์˜ ๋ชฉํ‘œ๋Š”

  • ์ง„์งœ ์˜ํ™” ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒ€์ƒ‰ ์‚ฌ์ดํŠธ ๋งŒ๋“ค๊ธฐ
  • HTML,ย CSS,ย JavaScript๋งŒ์œผ๋กœ API์™€ ์†Œํ†ตํ•˜๋ฉฐ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งŒ๋“ค๊ธฐ
  • ์˜ํ™” ํŒฌ๋“ค์„ ์œ„ํ•œย ๋ฉ‹์ง„ UI๋กœ, ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œํ˜„ํ•˜๊ธฐ
  • ๐Ÿฆธโ€โ™‚๏ธ API ๋งˆ์Šคํ„ฐ: ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๋Š” ์ฒซ ๊ฑธ์Œ์œผ๋กœ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ• ์ตํžˆ๊ธฐ!

์ผ๋‹จ ๋‚˜๋Š” [์ง‘์ค‘๋ฐ˜]์ด์—ˆ๊ธฐ๋•Œ๋ฌธ์— ๋ถ๋งˆํฌ๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ ๋์ง€๋งŒ,
์‹œ๋„๋Š” ํ•ด๋ณธ ์ข‹์€ ํ”„๋กœ์ ํŠธ ์˜€๋‹ค. ์ผ๋‹จ ์ง„ํ–‰๊ณผ์ •์„ ๋ณด์—ฌ์ฃผ์ž๋ฉด

Day 1: 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 ํ˜ธ์ถœ ์ค‘ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ–ˆ๋‹ค.

Day 2: ์˜ํ™” ์นด๋“œ ๋ฆฌ์ŠคํŠธ UI ๊ตฌํ˜„

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  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

์ด๋Ÿฐ ๊ตฌ์กฐ์˜ ์˜ํ™” ์นด๋“œ๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค !!!! ๐Ÿ˜‚

Day 3: ์˜ํ™” ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ๊ตฌํ˜„

๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ๊ตฌํ˜„์˜ ์กฐ๊ฑด์ด ์žˆ์—ˆ๋‹ค ๋ฐ”๋กœ ์•„๋ž˜์ฒ˜๋Ÿผ !

  • ๊ฒ€์ƒ‰์ฐฝ์„ ๋งŒ๋“ค๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ํ‚ค์›Œ๋“œ์— ๋งž์ถฐย ์˜ํ™” ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•„ํ„ฐ๋งํ•˜์„ธ์š”.
  • ๊ฒ€์ƒ‰ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๊ฑฐ๋‚˜ย Enter ํ‚ค๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ํ•ด๋‹น ํ‚ค์›Œ๋“œ๋ฅผ ํฌํ•จํ•œ ์˜ํ™”๋“ค๋งŒ ๋ฆฌ์ŠคํŠธ์— ๋‚˜ํƒ€๋‚˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • ํ˜น์€, ๊ฒ€์ƒ‰์ฐฝ์— ์ž…๋ ฅ์— ๋”ฐ๋ผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์˜ํ™” ๊ฒ€์ƒ‰์ด ๋˜๋„๋ก ๊ตฌํ˜„ํ•ด์ฃผ์…”๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.
  • ์ค‘์š” ํฌ์ธํŠธ: ์˜๋ฌธ์œผ๋กœ ์ง„ํ–‰ ํ•  ๊ฒฝ์šฐ, ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ ์—†์ด ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์„ธ์š”.
// ๊ฒ€์ƒ‰ ํผ๊ณผ ๊ฒ€์ƒ‰ ์ž…๋ ฅ์ฐฝ ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์™€์ฃผ๊ณ ,
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ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ๋‹ค ํ•ด๊ฒฐ !!!!!!!!!!

Day 4: ์˜ํ™” ์ƒ์„ธ ํŽ˜์ด์ง€ ๊ตฌํ˜„

์ด ๋ถ€๋ถ„์€ ํŒ€ ์†Œ๊ฐœ ๋ฏธ๋‹ˆ ํ”„๋กœ์ ํŠธ์—์„œ ๋ชจ๋‹ฌ์„ ํ•œ ๋ฒˆ ๋ดค์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ชจ๋‹ฌ์„ ์ฃผ๋ฉด ๋  ๊ฑฐ ๋ผ๋Š” ์ƒ๊ฐ์„ ํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ๋งˆ์นจ ์กฐ๊ฑด๋„ !
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();
  }
});

๋ชจ๋‹ฌ์„ ๋‹ซ๋Š” ๋ฐฉ๋ฒ•์„ ๋‚˜๋Š” ๋‘๊ฐ€์ง€๋ฅผ ๊ตฌํ˜„ํ–ˆ๋Š”๋ฐ

  • ๋‹ซ๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ
  • ๋ชจ๋‹ฌ ๋ฐ”๊นฅ ์˜์—ญ์„ ํด๋ฆญ ํ•  ๋•Œ

์ด๋ ‡๊ฒŒ ํ‘œํ˜„์„ ํ•˜๊ณ  ๋‚˜๋‹ˆ๊นŒ ๋‹ซ๊ธฐ ๋ฒ„ํŠผ์˜ ๊ฐ€์‹œ์„ฑ๊ณผ ์ƒ๊ด€์—†์ด ์‚ฌ์šฉ์ž๊ฐ€ ์•„๋ฌด๋ฐ๋‚˜ ํด๋ฆญํ•ด๋„ ๋ชจ๋‹ฌ์ด ๋‹ซํ˜€์„œ ์‚ฌ์šฉ์„ฑ์ด ํŽธ๋ฆฌ ํ•  ๊ฑฐ๋ผ๊ณ  ํŒ๋‹จํ–ˆ๋‹ค ๐Ÿค”โ—

Day 5: ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ๋Œ์•„์˜ค๊ธฐ ๋ฐ ์ฝ”๋“œ ์ •๋ฆฌ

  • ์˜ํ™” ์ƒ์„ธ ํŽ˜์ด์ง€๋‚˜ ๋ชจ๋‹ฌ์—์„œ ๋‹ค์‹œ ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ๋Œ์•„๊ฐ€๋Š”ย "๋’ค๋กœ ๊ฐ€๊ธฐ"ย ๋˜๋Š”ย "๋‹ซ๊ธฐ"ย ๋ฒ„ํŠผ์„ ๊ตฌํ˜„ํ•˜์„ธ์š”.
  • ์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ๋Œ์•„๊ฐˆ ๋•Œ,ย ์›๋ž˜์˜ ์˜ํ™” ๋ฆฌ์ŠคํŠธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋„๋ก ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
let bookmarkPageState = false;

bookmarkReverseBtn.addEventListener("click", (e) => {
  bookmarkPageState = false;
  displayMovies(allMovies);
  bookmarkBtn.style.display = "block";
  bookmarkReverseBtn.style.display = "none";
});

์‚ฌ์‹ค ๋ถ๋งˆํฌ ๋ถ€๋ถ„ ๋ถ€ํ„ฐ๋Š” ๋‹ค๋ฅธ๋ถ„์ด๋‚˜ ๊ตฌ๊ธ€๋ง์˜ ๋„์›€์„ ๋„ˆ๋ฌด ์ ˆ์‹คํžˆ ๋ฐ›์•˜๋‹ค. ๋ถ๋งˆํฌ ์‚ญ์ œ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ฒŒ๋˜๋ฉด bookmarkPageState = false;๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค. ์ „์ฒด ์˜ํ™” ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ !
๊ทธ๋ฆฌ๊ณ  displayMovies(allMovies);๋กœ allmovies์— ์žˆ๋Š” ์˜ํ™” ๋ชฉ๋ก์„ ๋‹ค์‹œ ํ‘œ์‹œํ•˜๊ฒŒ ํ•ด์คฌ๋‹ค. ๊ทธ ๋’ค์— ๋ฒ„ํŠผ์„ ๋‹ค์‹œ ๋ถ๋งˆํฌ ์‚ญ์ œ ๋ฒ„ํŠผ์„ ๊ฐ์ถ”๊ณ  ์ถ”๊ฐ€ ๋ฒ„ํŠผ์ด ๋ณด์ผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์—ˆ๋‹ค.

Day 6: ๋ชจ๋“ˆํ™” ๋ฐ ์ฝ”๋“œ ๋ถ„๋ฆฌ

์‚ฌ์‹ค ๋ชจ๋“ˆํ™”๊ฐ€ ์ •ํ™•ํžˆ ๋ฌด์ง€ ๋‚˜๋Š” ๋„ˆ๋ฌด ์–ด๋ ต๊ณ  ์ฝ”๋“œ๋Š” ๋ถ„๋ฆฌ๋ฅผ ์ตœ๋Œ€ํ•œ ํ•ด์คฌ๋‹ค.
๋ชจ๋‹ฌ, ๊ฒ€์ƒ‰, api, ๋ถ๋งˆํฌ js ๋ฅผ ๋”ฐ๋กœ ํ•ด์ฃผ์—ˆ๊ณ , css๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋”ฐ๋กœ ๋ถ„๋ฆฌํ•ด์„œ ์ž‘์„ฑํ–ˆ๋‹ค.

Day 7: ๋””๋ฒ„๊น… ๋ฐ ์ตœ์ข… ์ œ์ถœ ์ค€๋น„

๋””๋ฒ„๊น…์ด ์ •ํ™•ํžˆ ๋ญ”์ง€ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์› ์ง€๋งŒ ์ฝ˜์†”์ฐฝ์— ๋‚ด๊ฐ€ ๊ฐ€์ ธ์˜จ ์˜ํ™”๋“ค์˜ ๋ชฉ๋ก์ด ๋œจ๊ณ ,
์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š” ๋ถ€๋ถ„๋„ ์—†์—ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ตœ์ข… ๊ตฌํ˜„ ํ™”๋ฉด์„ ๋ณด์—ฌ์ฃผ์ž๋ฉด,

์—…๋กœ๋“œ์ค‘..


๐Ÿ˜–๊ฐœ์ธ๊ณผ์ œ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์•„์‰ฌ์› ๋˜ ์ 

  • ๋ถ๋งˆํฌ ๋ถ€๋ถ„์„ ๋‚ด ํž˜์œผ๋กœ ์Šค์Šค๋กœ ๊ตฌํ˜„ ํ•œ ๋Š๋‚Œ์ด ์•„๋‹ˆ๋ผ ๊ตฌ๊ธ€๋ง๊ณผ ๋„์›€์„ ๋ฐ›์•„ ๊ตฌํ˜„ ํ•œ ๊ฒƒ ๊ฐ™๋‹จ ์ 
  • UI๋ฅผ ์ข€ ๋” ์‚ฌ์šฉ์ž๊ฐ€ ํŽธํ•˜๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ•˜์ง€ ๋ชปํ•œ ์ 
    (์žฅ๋ฅด๋ณ„๋กœ ๋‚˜๋ˆˆ๋‹ค๋˜๊ฐ€ ์Šฌ๋ผ์ด๋”๋ฅผ ๋งŒ๋“ ๋‹ค๋˜๊ฐ€ ํ•˜๋Š” ์ )
  • ์ธ๊ธฐ ์˜ํ™” ๋ชฉ๋ก ๋ถ€๋ถ„์„ ๋ˆŒ๋ €์„ ๋•Œ ํ™ˆ์œผ๋กœ ๋Œ์•„๊ฐ€๊ฒŒํ•˜๋Š”๊ฑธ ํ•  ๊ฑธ ๊ทธ๋žฌ๋‹ค ์‹ถ์€ ์ 

๐Ÿ˜Š๊ฐœ์ธ ๊ณผ์ œ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์ž˜ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ ์ 

  • ๊ฒ€์ƒ‰ ๋ถ€๋ถ„์„ ๊ตฌํ˜„์— ์„ฑ๊ณตํ–ˆ๋‹ค๋Š” ์ 
  • ๋ชจ๋‹ฌ์„ ์ž˜ ๋„์› ๋‹ค๋Š” ์ 
profile
๋„์  ๋„์  ๋ฐฐ์šด ๊ฑธ ์ ์Šต๋‹ˆ๋‹ค / FRONT-END STUDY VELOG

0๊ฐœ์˜ ๋Œ“๊ธ€