こんにちは。KOUKIです。
本記事は、Udemyの「50 Projects In 50 Days – HTML, CSS & JavaScript」で学習したことを載せています。
<目次>
実装するもの
demoは「こちら」で確認できます。
環境構築
簡単な環境構築をお願いします。
必要なファイルは、以下の通りです。
1 2 3 4 5 6 |
$ tree . ├── index.html ├── script.js └── style.css |
CSS版
ページ(HTML)の作成
最初にページを作成しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="style.css" /> <title>Movie App</title> </head> <body> <header> <form id="form"> <input type="text" id="search" class="search" placeholder="Search"> </form> </header> <main id="main"></main> <script src="script.js"></script> </body> </html> |
このHTMLをブラウザ上で表示すると以下のようになります。

スタイル(CSS)を装飾
次にスタイルを記述しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap'); :root { --primary-color: #22254b; --secondary-color: #373b69; } * { box-sizing: border-box; } body { background-color: var(--primary-color); font-family: 'Poppins', sans-serif; margin: 0; } header { padding: 1rem; display: flex; justify-content: flex-end; background-color: var(--secondary-color); } .search { background-color: transparent; border: 2px solid var(--primary-color); border-radius: 50px; font-family: inherit; font-size: 1rem; padding: 0.5rem 1rem; color: #fff; } .search::placeholder { color: #7378c5; } .search:focus { outline: none; background-color: var(--primary-color); } main { display: flex; flex-wrap: wrap; justify-content: center; } .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; } .movie img { width: 100%; } .movie-info { color: #eee; display: flex; align-items: center; justify-content: space-between; padding: 0.5rem 1rem 1rem; letter-spacing: 0.5px; } .movie-info h3 { margin-top: 0; } .movie-info span { background-color: var(--primary-color); padding: 0.25rem 0.5rem; border-radius: 3px; font-weight: bold; } .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; left: 0; bottom: 0; right: 0; max-height: 100%; transform: translateY(101%); overflow-y: auto; transition: transform 0.3s ease-in; } .movie:hover .overview { transform: translateY(0); } |
ここまで実装すると以下のようになります。

JavaScriptの実装
TMDBのAPIのドキュメントを確認しながら、開発を進めていきましょう。
リクエスト先を定数で定義
最初にリクエスト先を定数で定義します。
今回使うのは、「Discover」、「Images」、「Search」の3つです。
Images: 取得データに含まれるファイル格納場所などの情報を提供
Search: 映画を検索する
1 2 3 4 5 6 7 |
// 定数 // Discover const API_URL = 'https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=3fd2be6f0c70a2a598f084ddfb75487c&page=1' // Images const IMG_PATH = 'https://image.tmdb.org/t/p/w1280' // Search const SEARCH_API = 'https://api.themoviedb.org/3/search/movie?api_key=3fd2be6f0c70a2a598f084ddfb75487c&query="' |
要素を取得
次に、HTMLのform要素を取得します。
1 2 3 4 5 |
// 定数 // 要素を取得 const main = document.getElementById('main') const form = document.getElementById('form') const search = document.getElementById('search') |
async/awaitで非同期通信
次は、非同期関数のasync/awaitを使って、Movie情報を取得しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 |
// 要素を取得 // 映画情報を取得 getMovies(API_URL) // async/awaitで非同期処理 async function getMovies(url) { // APIヘGETリクエスト const res = await fetch(url) // 取得したデータをJSON形式で取得 const data = await res.json() console.log(data) } |
Chromeのデベロッパーツールを開くとMovie情報が取得できていることが確認できます。

formにSubmitイベントを登録
次に、formから検索を行えるようにしましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// formから検索できるようにする form.addEventListener('submit', (e) => { // フォームのデフォルトの動きを禁止 // ここではページのリダイレクトをキャンセルしている e.preventDefault() // 検索文字列取得 const searchTerm = search.value if(search && searchTerm !== '') { // 検索文字列を元に検索をする getMovies(SEARCH_API + searchTerm) // 検索文字列を削除 search.value = '' } else { // ページを再読み込み // 検索キーワードない状態で検索すると初期状態のデータを表示できる // Searchで検索した結果をクリアしたい時などに使える window.location.reload() } }) |
これで、検索が行えるようになりました。
検索窓に「Test」と打ち込んで、取得したデータを確認してみましょう。

MovieパネルをHTMLに埋め込む
次に、APIから取得したデータをMovieパネルにして、HTMLに埋め込みます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
async function getMovies(url) { ... // Movieを表示 showMovies(data.results) } function showMovies(movies) { // 画面初期化 main.innerHTML = '' movies.forEach((movie) => { // オブジェクトから各変数に格納 const { title, poster_path, vote_average, overview } = movie // Movieパネルを作成 const movieEl = document.createElement('div') movieEl.classList.add('movie') // MoveパネルをHTMLに埋め込む 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) }) |
getClassByRate関数を作成していないため、まだ画面には表示されませんが、これでOKです。
getClassByRateの作成
getClassByRateは、映画の評価を示す数値の色分けをおこないます。

1 2 3 4 5 6 7 8 9 10 |
// 人気順にクラス分けをする function getClassByRate(vote) { if(vote >= 8) { return 'green' } else if(vote >= 5) { return 'orangge' } else { return 'red' } } |
これで完成です。
おわりに
以前にもAPIを使ったアプリケーションを学習しましたが、やはり面白いですね。今回作成したものをフォーマット化すれば、TMDB API以外で提供されているAPIでも同じことができるはずです。
それでは、また!
JavaScriptまとめ
JavaScript ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
// 定数 // Discover const API_URL = 'https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=3fd2be6f0c70a2a598f084ddfb75487c&page=1' // Images const IMG_PATH = 'https://image.tmdb.org/t/p/w1280' // Search const SEARCH_API = 'https://api.themoviedb.org/3/search/movie?api_key=3fd2be6f0c70a2a598f084ddfb75487c&query="' // 要素を取得 const main = document.getElementById('main') const form = document.getElementById('form') const search = document.getElementById('search') // 映画情報を取得 getMovies(API_URL) // async/awaitで非同期処理 async function getMovies(url) { // APIヘGETリクエスト const res = await fetch(url) // 取得したデータをJSON形式で取得 const data = await res.json() // Movieを表示 showMovies(data.results) } function showMovies(movies) { // 画面初期化 main.innerHTML = '' movies.forEach((movie) => { // オブジェクトから各変数に格納 const { title, poster_path, vote_average, overview } = movie // Movieパネルを作成 const movieEl = document.createElement('div') movieEl.classList.add('movie') // MoveパネルをHTMLに埋め込む 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) }) } // 人気順にクラス分けをする function getClassByRate(vote) { if(vote >= 8) { return 'green' } else if(vote >= 5) { return 'orangge' } else { return 'red' } } // formから検索できるようにする form.addEventListener('submit', (e) => { // フォームのデフォルトの動きを禁止 // ここではページのリダイレクトをキャンセルしている e.preventDefault() // 検索文字列取得 const searchTerm = search.value if(search && searchTerm !== '') { // 検索文字列を元に検索をする getMovies(SEARCH_API + searchTerm) // 検索文字列を削除 search.value = '' } else { // ページを再読み込み // 検索キーワードない状態で検索すると初期状態のデータを表示できる // Searchで検索した結果をクリアしたい時などに使える window.location.reload() } }) |
コメントを残す
コメントを投稿するにはログインしてください。