質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

659閲覧

難易度別に分けたクイズの問題が正しく出題されない

bob-kitchin

総合スコア11

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/09/09 12:03

編集2021/09/09 12:04

前提・実現したいこと

現在クイズゲームを作っていて、難易度別に出題されるクイズの内容を変えたいのですが不明な点が2点あります。
1点目は、中級を選択すると1問目は正しく出題されるのですが、2問目以降は初級に設定してある問題が出題されてしまいます。
2点目は、中級の1問目がどの選択肢を選んでも不正解になってしまいます。
検証してもエラーは出ませんでした。
1問目の問題文は正しいので、恐らくJavaScriptのコードの159行目(const clickHandlerM)以降に問題があるのではないかと思い確認はしたのですが、どこに問題点があるのかわかりません。
改善策をお願いします。

該当のソースコード

HTML

1<!doctype html> 2<html class="no-js" lang=""> 3 4<head> 5 <meta charset="utf-8"> 6 <title></title> 7 <meta name="description" content=""> 8 <meta name="viewport" content="width=device-width, initial-scale=1"> 9 10 <meta property="og:title" content=""> 11 <meta property="og:type" content=""> 12 <meta property="og:url" content=""> 13 <meta property="og:image" content=""> 14 15 <link rel="manifest" href="site.webmanifest"> 16 <link rel="apple-touch-icon" href="icon.png"> 17 <!-- Place favicon.ico in the root directory --> 18 19 <!-- CSS only --> 20<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"> 21 22 <meta name="theme-color" content="#fafafa"> 23 24</head> 25<body> 26 27 <style> 28 29 .container{ 30 margin-right: auto; 31 margin-left: auto; 32 max-width: 700px; 33 34 background-image:url(haikei.png); 35 background-size:cover; 36 background-position:center center; 37 background-repeat: no-repeat; 38 object-fit: cover; 39 position: relative; 40 } 41 42 .question{ 43 text-align:center; 44 position:absolute; 45 border: solid 2px gray; 46 } 47 48 .fixed-bottom{ 49 margin: 0; 50 position:absolute; 51 text-align:center; 52 } 53 54 .answer{ 55 border: solid 2px gray; 56 } 57 58 .smile{ 59 position: absolute; 60 animation: 61 name1 3s step-end 0s infinite normal; 62 z-index: 2; 63 } 64 65 .sleep{ 66 position: absolute; 67 z-index: 1; 68 } 69 70 @keyframes name1{ 71 0%{ opacity:1; } 72 73 35%{ opacity:0; } 74 75 40%{ opacity:1; } 76 77 80%{ opacity:0; } 78 79 85%{ opacity:1; } 80 81 95%{ opacity:0; } 82 83 100%{ opacity:1; } 84 } 85 86 </style> 87 88<div class="p-4"> 89</div><!---- space --> 90 91 <div id="top"class="container mt-5 py-5 px-0"> 92 93 <div id="question" class="row justify-content-center"> 94 <div id=questionText class="question fixed-top">問題文</div> 95 </div><!---- question --> 96 97 <div id="button-d"class="row flex-column d-flex align-items-center justify-content-center" style="margin:0;"> 98 <h1 class="col-3 text-center mb-5">クイズ</h1> 99 <button type="button" id="easy"class="col-2 btn btn-primary mb-3 w-25">初級</button> 100 <button type="button" id="middle"class="col-2 ml-1 btn btn-primary mb-3 w-25">中級</button> 101 <button type="button" id="difficult"class="col-2 ml-1 btn btn-primary mb-3 w-25">上級</button> 102 <button type="button" id="hell"class="col-2 ml-1 btn btn-primary w-25">冥府級</button> 103 </div> <!---- difficulty level --> 104 105 <div id="answer"class="row fixed-bottom flex-row row-cols-2 justify-content-center"> 106 <div type="button" id="choiseF" class="answer col py-2 px-0">選択肢1</div> 107 <div type="button" id="choiseS" class="answer col py-2 px-0">選択肢2</div> 108 <div type="button" id="choiseT" class="answer col py-2 px-0">選択肢3</div> 109 <div type="button" id="choiseFo" class="answer col py-2 px-0">選択肢4</div> 110 </div> <!---- answer --> 111 112 <img class="smile position-absolute bottom-0 start-0" src="smile.png" alt=""> 113 114 <img class="sleep position-absolute bottom-0 start-0" src="sleep.png" alt=""> 115 116 </div><!---- container --> 117 118 <script src="quiz.js"></script> 119 120</body> 121 122</html>

JavaScript

1const $question=document.getElementById("question")//問題文の親要素 2const $answer=document.getElementById("answer")//選択肢の親要素 3const $button=document.getElementById("button-d")//難易度 4const $easy=document.getElementById("easy")//初級 5const $middle=document.getElementById("middle")//中級 6 7let $questionText=document.getElementById("questionText")//問題文 8let $answerW=document.getElementsByClassName("answer")//選択肢 9 10const answerLength=$answerW.length//選択肢の数 11 12 13 14const questionOriginal=$question.style.visibility; 15const answerOriginal=$answer.style.visibility; 16//表示用 17 18$question.style.visibility = "hidden"; 19$answer.style.visibility = "hidden"; 20//非表示 21 22 23$button.onclick = function() { 24 $button.style.visibility ="hidden"; 25 $question.style.visibility=questionOriginal; 26 $answer.style.visibility=answerOriginal; 27 }; 28 //画面切り替え 29 30 31 const quizE=[ 32 { 33 questionBox:"ミラ様のフルネームは?", 34 answerBox:[ 35 "ミラ・フェンリエッタ", 36 "ミラ・フェンリス", 37 "ミラ・フェンリエヌト", 38 "ミラ・フェルート" 39 ], 40 correct:"ミラ・フェンリエッタ" 41 42 },{ 43 questionBox:"ミラ様の種族は?", 44 answerBox:[ 45 "サキュバス", 46 "悪魔", 47 "人間", 48 "ヴァンパイア" 49 ], 50 correct:"悪魔" 51 },{ 52 questionBox:"今まで登場したミラ様の職業の中で、一番多いのは次の内どれ?", 53 answerBox:[ 54 "剣士", 55 "アーチャー", 56 "魔導士", 57 "ルーンセイバー" 58 ], 59 correct:"魔導士" 60 } 61 ]; 62 63 const quizM=[ 64 { 65 questionBox:"茶熊ミラ様と部活が違うキャラは次の内誰?", 66 answerBox:[ 67 "ジュダ", 68 "シエラ", 69 "コヨミ", 70 "コリン" 71 ], 72 correct:"シエラ" 73 74 },{ 75 questionBox:"今までの周年パーティでミラ様の登場が最も早かったのは何年目?", 76 answerBox:[ 77 "3周年", 78 "4周年", 79 "5周年", 80 "6周年" 81 ], 82 correct:"5周年" 83 },{ 84 questionBox:"イベントストーリー「ミラ様に懺悔しなさい!」にて一番最後にミラ様に懺悔しに来たキャラは誰?", 85 answerBox:[ 86 "キャロ", 87 "ユイ", 88 "テレーゼ", 89 "マイ" 90 ], 91 correct:"テレーゼ" 92 } 93]; 94 //問題箱 95 const quizLengthE=quizE.length; 96 const quizLengthM=quizM.length; 97 let quizIndex=0; 98 99 100 const setUpQuizE=()=>{ 101 $questionText.innerHTML=quizE[quizIndex].questionBox 102 let answerIndex = 0; 103 while(answerIndex<answerLength){ 104 $answerW[answerIndex].innerHTML = quizE[quizIndex].answerBox[answerIndex]; 105 answerIndex++; 106 //answer.lengthで省略 107 } 108 }; 109 110 $easy.onclick = function(){ 111 setUpQuizE(); 112 }; 113 114 const clickHandlerE =(e)=>{ 115 if(quizE[quizIndex].correct===e.target.innerHTML){ 116 window.alert("正解!"); 117 } 118 else{ 119  window.alert("不正解!"); 120 } 121 122 quizIndex++; 123 124 if(quizIndex<quizLengthE){ 125 setUpQuizE(); 126 } 127 else{ 128 window.alert("終了!"); 129 } 130 }; 131 //選択肢をクリックしたときの動作 132 133 let handlerIndex=0; 134 while(handlerIndex<answerLength){ 135 $answerW[handlerIndex].addEventListener("click",(e)=>{ 136 clickHandlerE(e); 137 }); 138 handlerIndex++; 139 }; 140 //clickHandlerEを全ての選択肢に設定 141 142 143 //ここから中級 144 const setUpQuizM=()=>{ 145 $questionText.innerHTML=quizM[quizIndex].questionBox 146 let answerIndex = 0; 147 while(answerIndex<answerLength){ 148 $answerW[answerIndex].innerHTML = quizM[quizIndex].answerBox[answerIndex]; 149 answerIndex++; 150 //answer.lengthで省略 151 } 152 }; 153 154 $middle.onclick = function(){ 155 setUpQuizM(); 156 }; 157 158 159 const clickHandlerM =(e)=>{ 160 if(quizM[quizIndex].correct===e.target.innerHTML){ 161 window.alert("正解!"); 162 } 163 else{ 164  window.alert("不正解!"); 165 } 166 167 quizIndex++; 168 169 if(quizIndex<quizLengthM){ 170 setUpQuizM(); 171 } 172 else{ 173 window.alert("終了!"); 174 } 175 }; 176 //選択肢をクリックしたときの動作 177 178 while(handlerIndex<answerLength){ 179 $answerW[handlerIndex].addEventListener("click",(e)=>{ 180 clickHandlerM(e); 181 }); 182 handlerIndex++; 183 }; 184 //clickHandlerEを全ての選択肢に設定

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

原因

131行目~140行目

JavaScript

1 //選択肢をクリックしたときの動作 2 3 let handlerIndex=0; 4 while(handlerIndex<answerLength){ 5 $answerW[handlerIndex].addEventListener("click",(e)=>{ 6 clickHandlerE(e); 7 }); 8 handlerIndex++; 9 }; 10 //clickHandlerEを全ての選択肢に設定

インデントのせいで分かりづらいですが、この箇所は実際にはページを読み込んだタイミングで実行されます。そのため、選択肢のボタンには問題の難易度に関わらず初級用のイベントリスナーが設定され、中級を選んでも途中から初級と同じ処理が実行されてしまいます。

176行目~

JavaScript

1 //選択肢をクリックしたときの動作 2 3 while(handlerIndex<answerLength){ 4 $answerW[handlerIndex].addEventListener("click",(e)=>{ 5 clickHandlerM(e); 6 }); 7 handlerIndex++; 8 }; 9 //clickHandlerEを全ての選択肢に設定

こちらも、ページを読み込んだタイミングで実行されています。ただしhandlerIndexの値が131行目~140行目の処理後の値のままなので、whileループの中身は1度も実行されません。

修正例(一部)

27行目から余計なインデントがついているせいで、コードがいつ実行されるのかが分かりにくくなっています。
コードの読みやすさのためにも、インデントは正確につけましょう。

難易度のボタンをクリックしたタイミングで、難易度に応じたイベントリスナーを選択肢のボタンに設定すると正しく動きます。

JavaScript

1//110行目~ 2$easy.onclick = function(){ 3 setUpQuizE(); 4 let handlerIndex=0; 5 while(handlerIndex<answerLength){ 6 $answerW[handlerIndex].addEventListener("click",(e)=>{ 7 clickHandlerE(e); 8 }); 9 handlerIndex++; 10 }; 11 //clickHandlerEを全ての選択肢に設定 12}; 13 14//133行目~139行目のコードは削除 15 16//154行目~ 17$middle.onclick = function(){ 18 setUpQuizM(); 19 let handlerIndex=0; 20 while(handlerIndex<answerLength){ 21 $answerW[handlerIndex].addEventListener("click",(e)=>{ 22 clickHandlerM(e); 23 }); 24 handlerIndex++; 25 }; 26 //clickHandlerMを全ての選択肢に設定 27}; 28 29//176行目~のコードは削除

投稿2021/09/09 13:59

編集2021/09/09 15:06
luuguas

総合スコア501

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bob-kitchin

2021/09/09 15:18 編集

ありがとうございます。luuuguasさんの修正例を参考に修正したところ無事解決しました。 今後はインデントや関数が実行されるタイミングについても気を付けようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問