こんにちは。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 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!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>Quiz App</title> </head> <body> <div class="quiz-container" id="quiz"> <div class="quiz-header"> <h2 id="question">Question text</h2> <ul> <li> <input type="radio" name="answer" id="a" class="answer"> <label for="a" id="a_text">Question</label> </li> <li> <input type="radio" name="answer" id="b" class="answer"> <label for="b" id="b_text">Question</label> </li> <li> <input type="radio" name="answer" id="c" class="answer"> <label for="c" id="c_text">Question</label> </li> <li> <input type="radio" name="answer" id="d" class="answer"> <label for="d" id="d_text">Question</label> </li> </ul> </div> <button id="submit">Submit</button> </div> <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 |
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap'); * { box-sizing: border-box; } body { background-color: #b8c6db; background-image: linear-gradient(315deg, #b8c6db 0%, #f5f7fa 100%); font-family: 'Poppins', sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin: 0; } .quiz-container { background-color: #fff; border-radius: 10px; box-shadow: 0 0 10px 2px rgba(100, 100, 100, 0.1); width: 600px; overflow: hidden; } .quiz-header { padding: 4rem; } h2 { padding: 1rem; text-align: center; margin: 0; } ul { list-style-type: none; padding: 0; } ul li { font-size: 1.2rem; margin: 1rem 0; } ul li label { cursor: pointer; } button { background-color: #8e44ad; color: #fff; border: none; display: block; width: 100%; cursor: pointer; font-size: 1.1rem; font-family: inherit; padding: 1.3rem; } button:hover { background-color: #732d91; } button:focus { outline: none; background-color: #5e3370; } |
ここまで実装すると以下のようになります。

JavaScriptの実装
要素を取得
最初に、画面操作に必要な要素を取得します。
1 2 3 4 5 6 7 8 9 |
// 要素を取得 const quiz = document.getElementById('quiz') const answerEls = document.querySelectorAll('.answer') const questionEl = document.getElementById('question') const a_text = document.getElementById('a_text') const b_text = document.getElementById('b_text') const c_text = document.getElementById('c_text') const d_text = document.getElementById('d_text') const submitBtn = document.getElementById('submit') |
クイズデータの定義
画面に表示するクイズデータを定数で定義しましょう。
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 |
// 定数 const quizData = [ { question: "Which language runs in a web browser?", a: "Java", b: "C", c: "Python", d: "JavaScript", correct: "d", }, { question: "What does CSS stand for?", a: "Central Style Sheets", b: "Cascading Style Sheets", c: "Cascading Simple Sheets", d: "Cars SUVs Sailboats", correct: "b", }, { question: "What does HTML stand for?", a: "Hypertext Markup Language", b: "Hypertext Markdown Language", c: "Hyperloop Machine Language", d: "Helicopters Terminals Motorboats Lamborginis", correct: "a", }, { question: "What year was JavaScript launched?", a: "1996", b: "1995", c: "1994", d: "none of the above", correct: "b", }, ]; |
このアプリケーションでは、クイズデータの最大数は4つまでです。動的に決められるようになったら面白いですね。
クイズのロード
次にクイズのロード処理を実装しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
let currentQuiz = 0 let score = 0 // 後で使う loadQuiz() // クイズを表示する function loadQuiz() { deselectAnswers() // 後で設定 const currentQuizData = quizData[currentQuiz] questionEl.innerText = currentQuizData.question a_text.innerText = currentQuizData.a b_text.innerText = currentQuizData.b c_text.innerText = currentQuizData.c d_text.innerText = currentQuizData.d } |
ここでは、先ほど設定したクイズデータ(quizData)をinnerTextを使ってページに埋め込んでいます。
クイズ選択解除
クイズの選択項目は、HTMLのradioで作成しています。1ページ目のクイズに回答して、2ページ目に行くと前ページで選択した項目がチェックされた状態のままになってしまうため、解除処理が必要です。
1 2 3 4 |
// 選択を解除 function deselectAnswers() { answerEls.forEach(answerEl => answerEl.checked = false) } |
radioボックスなどのHTML要素はchecked属性を持っており、これがtrueの場合、選択状態になります。
回答取得
次は、回答を取得する処理を実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// 回答取得 function getSelected() { let answer answerEls.forEach(answerEl => { // ラジオボックスのchecked属性をチェック if(answerEl.checked) { // checked属性がついたinput要素のIDを取得 answer = answerEl.id } }) return answer } |
回答送信
最後に、回答送信処理を実装します。
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 |
// Submitボタンをクリックした時に発火 submitBtn.addEventListener('click', () => { // 回答取得 const answer = getSelected() // 未選択の場合は送信できないようにする if(answer) { // 正誤チェック if(answer === quizData[currentQuiz].correct) { // 正解の場合はスコアをインクリメント score++ } currentQuiz++ if(currentQuiz < quizData.length) { // クイズの読み込み loadQuiz() } else { // 結果発表 quiz.innerHTML = ` <h2>You answered ${score}/${quizData.length} questions correctly</h2> <button onclick="location.reload()">Reload</button> ` } } }) |
「location.reload()」は、ページのURLを再読み込みしてくれる便利なメソッドです。リロード処理などでよく使いますね。
これで完成です。
おわりに
クイズ系のアプリケーションは、今まで実装したことがなかったですね。
このアプリが作れるようになるとアンケートアプリなど、類似したアプリケーションにも応用ができそうですよね。
それでは、また!
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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
// 要素を取得 const quiz = document.getElementById('quiz') const answerEls = document.querySelectorAll('.answer') const questionEl = document.getElementById('question') const a_text = document.getElementById('a_text') const b_text = document.getElementById('b_text') const c_text = document.getElementById('c_text') const d_text = document.getElementById('d_text') const submitBtn = document.getElementById('submit') // 定数 const quizData = [ { question: "Which language runs in a web browser?", a: "Java", b: "C", c: "Python", d: "JavaScript", correct: "d", }, { question: "What does CSS stand for?", a: "Central Style Sheets", b: "Cascading Style Sheets", c: "Cascading Simple Sheets", d: "Cars SUVs Sailboats", correct: "b", }, { question: "What does HTML stand for?", a: "Hypertext Markup Language", b: "Hypertext Markdown Language", c: "Hyperloop Machine Language", d: "Helicopters Terminals Motorboats Lamborginis", correct: "a", }, { question: "What year was JavaScript launched?", a: "1996", b: "1995", c: "1994", d: "none of the above", correct: "b", }, ]; let currentQuiz = 0 let score = 0 loadQuiz() // クイズを表示する function loadQuiz() { deselectAnswers() const currentQuizData = quizData[currentQuiz] questionEl.innerText = currentQuizData.question a_text.innerText = currentQuizData.a b_text.innerText = currentQuizData.b c_text.innerText = currentQuizData.c d_text.innerText = currentQuizData.d } // 選択を解除 function deselectAnswers() { answerEls.forEach(answerEl => answerEl.checked = false) } // 回答取得 function getSelected() { let answer answerEls.forEach(answerEl => { // ラジオボックスのchecked属性をチェック if(answerEl.checked) { // checked属性がついたinput要素のIDを取得 answer = answerEl.id } }) return answer } // Submitボタンをクリックした時に発火 submitBtn.addEventListener('click', () => { // 回答取得 const answer = getSelected() // 未選択の場合は送信できないようにする if(answer) { // 正誤チェック if(answer === quizData[currentQuiz].correct) { // 正解の場合はスコアをインクリメント score++ } currentQuiz++ if(currentQuiz < quizData.length) { // クイズの読み込み loadQuiz() } else { // 結果発表 quiz.innerHTML = ` <h2>You answered ${score}/${quizData.length} questions correctly</h2> <button onclick="location.reload()">Reload</button> ` } } }) |
コメントを残す
コメントを投稿するにはログインしてください。