前提・実現したいこと
Youtubeの”セイト先生のWeb・IT塾”さんの【JavaScript超入門講座】基礎文法だけでクイズゲームのアプリを開発!を改良してみようと思い、制作中です。
動画では4択と決められていますが、**「選択肢の数に応じてボタンの数も変化させてみよう」**をやってみたくて、予めbuttonは書かずに__createElement("button")__で書いていて、それを__answersBox.appendChild($button)__で表示しています。
想定している動きは
選択肢をボタンに1つずつ表示、クリックで正誤判定(alert)、次の問題へ移る__(再びsetupQuiz)__時に1問目を消し、2問目を表示したいと考えていて、問題数分繰り返して、残りの問題が無くなったら最後に正解数を表示します。
ソースコードの状態では2問目→3問目と表示できますが、前の問題が消えずに残ってしまいますし、2問目と3問目はクリックの対象からも外れています。この点を解決するためのコードまたヒントだけでも教えていただけると助かります。
お時間ある方回答よろしくお願いいたします。
発生している問題・エラーメッセージ
貼り付けたソースコードでエラーは起きていないのですが、setQuiz関数の$button.textContent を$button[quizIndex].textContentや$button[i].textContentにすると「undefinedにtextContentはsetできない」とエラー
index3.html:118 Uncaught TypeError: Cannot set property 'textContent' of undefined at setupQuiz (index3.html:118) at index3.html:172
該当のソースコード
html,javascript
1<!DOCTYPE html> 2<html class="no-js" lang=""> 3 <head> 4 <meta charset="utf-8" /> 5 <title></title> 6 <meta name="description" content="" /> 7 <meta name="viewport" content="width=device-width, initial-scale=1" /> 8 9 <meta property="og:title" content="" /> 10 <meta property="og:type" content="" /> 11 <meta property="og:url" content="" /> 12 <meta property="og:image" content="" /> 13 14 <link rel="manifest" href="site.webmanifest" /> 15 <link rel="apple-touch-icon" href="icon.png" /> 16 <!-- Place favicon.ico in the root directory --> 17 18 <!-- CSS only --> 19 <link 20 href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" 21 rel="stylesheet" 22 integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" 23 crossorigin="anonymous" 24 /> 25 26 <meta name="theme-color" content="#fafafa" /> 27 </head> 28 29 <body> 30 <div class="container"> 31 <div id="js-question" class="alert alert-primary mt-4" role="alert"> 32 A simple primary alert—check it out! 33 </div> 34 35 <div id="answers-box" class="d-flex justify-content-center"> 36 <!-- <button type="button" class="btn btn-primary">Primary</button> 37 <button type="button" class="btn btn-primary ms-2">Primary</button> 38 <button type="button" class="btn btn-primary ms-2">Primary</button> 39 <button type="button" class="btn btn-primary ms-2">Primary</button> --> 40 </div> 41 </div> 42 43 <script> 44 const quiz = [ 45 { 46 question: "ハリソン・フォードが大好きなのは日本の何?", 47 answers: ["忍者", "酒", "祭り", "相撲", "城"], 48 correct: "忍者", 49 }, 50 { 51 question: "トム・クルーズは学生時代、何回転校した?", 52 answers: ["4", "7", "11", "14"], 53 correct: "14", 54 }, 55 { 56 question: "「シュワちゃん」のシュワルツェネッガー、正しいスペルは?", 57 answers: [ 58 "Schwalzeneger", 59 "Schwarzenegger", 60 "Shwarzeneger", 61 "Schwalzenegger", 62 "Schwarzeneger", 63 "Shwarzenegger", 64 ], 65 correct: "Schwarzenegger", 66 }, 67 ]; 68 69 const quizLength = quiz.length; 70 let quizIndex = 0; 71 let score = 0; 72 73 const answersBox = document.querySelector("#answers-box"); 74 75 76 // クイズの問題文、選択肢を定義 77 const setupQuiz = () => { 78 // 問題 79 document.querySelector("#js-question").textContent = 80 quiz[quizIndex].question; 81 82 // 選択肢 83 let buttonIndex = 0; 84 const buttonLength = quiz[quizIndex].answers.length; 85 86 87 for (i = 0; i < buttonLength; i++) { 88 const $button = document.createElement("button"); 89 90 $button.classList.add("btn", "btn-primary", "ms-2"); 91 $button.type = "button"; 92 93 console.log($button); 94 95 $button.textContent = quiz[quizIndex].answers[i]; 96 answersBox.appendChild($button); 97 } 98 }; 99 100 // const clearQuiz = () => { 101 // answersBox.removeChild(); 102 // } 103 104 const clickHandler = (e) => { 105 if (quiz[quizIndex].correct === e.target.textContent) { 106 window.alert("正解!!おめでとう"); 107 score++; 108 } else { 109 window.alert("不正解...残念"); 110 } 111 112 quizIndex++; 113 if (quizIndex < quizLength) { 114 // clearQuiz(); 115 setupQuiz(); 116 } else { 117 if (score === quizLength) { 118 window.alert( 119 "終了です。あなたの正解数は" + 120 score + 121 "/" + 122 quizLength + 123 "です! \n 全問正解!!素晴らしい!!" 124 ); 125 } else { 126 window.alert( 127 "終了です。あなたの正解数は" + 128 score + 129 "/" + 130 quizLength + 131 "です! \n 答えが知りたい方はまた遊んでください。" 132 ); 133 } 134 } 135 }; 136 137 // buttonをclickしたら正誤判定 138 const judge = () => { 139 const btn = document.querySelectorAll("button"); 140 let handlerIndex = 0; 141 while (handlerIndex < btn.length) { 142 btn[handlerIndex].addEventListener("click", (e) => { 143 clickHandler(e); 144 }); 145 handlerIndex++; 146 } 147 }; 148 149 setupQuiz(); 150 judge(); 151 </script> 152 </body> 153</html> 154
試したこと
コメントアウトで残しておきましたが、clearQuiz()関数として__answersBox
の中身を空にしようともしましたが、「removeChildはNodeが1つは必要、今はゼロ」とエラーになるため、なにか入れようと__answersBox.removeChild($button);にしたところ、関数が違うため「$button is not defined」とエラーでした。
補足情報(FW/ツールのバージョンなど)
windows,Chromeブラウザ,VSCodeエディタ使用
回答1件
あなたの回答
tips
プレビュー