前提・実現したいこと
お世話になっております。
現在、HTML/JavaScript/CSSを用いて、4択式の問題アプリを作成しております。
参考として以下のサイトのソースコードを使用しています。
参考サイト
上記参考サイトではconst myQuestions = [];の中にハードコーディングで
問題文を記述しておりますが、これをJSON形式で別だしにしたいと考えています。
JavaScriptは現在勉強中であり、皆様の知恵をお借りしたく、ここに投稿させていただきます。
何卒よろしくお願い申し上げます。
発生している問題・エラーメッセージ
現在、以下のエラーメッセージが出ています。
Uncaught TypeError: Cannot read property 'classList' of undefined
該当のソースコード
JavaScript
1(function() { 2 var myQuestions = []; 3 function jsonLoader(){ 4 $.ajax({ 5 type: 'GET', 6 url: 'ローカルにあるjsonファイルのフルパス', 7 dataType: 'json', 8 }).done(function(json, textStatus, jqXHR) { 9 jsonArray = JSON.parse(json); 10 for(var i = 0; i < jsonArray.length; i++){ 11 myQuestions.push({ 12 'question': jsonArray[i].question, 13 'answers': jsonArray[i].answers, 14 'correctAnswer': jsonArray[i].correctAnswer 15 }); 16 }; 17 console.log(myQuestions); 18 }).fail(function(jqXHR, textStatus, errorThrown){ 19 alert(errorThrown); 20 }); 21 } 22 23 24 function buildQuiz() { 25 jsonLoader() 26 const output = []; 27 console.log(myQuestions); 28 // for each question... 29 myQuestions.forEach((currentQuestion, questionNumber) => { 30 // we'll want to store the list of answer choices 31 const answers = []; 32 33 // and for each available answer... 34 for (letter in currentQuestion.answers) { 35 // ...add an HTML radio button 36 answers.push( 37 `<label> 38 <input type="radio" name="question${questionNumber}" value="${letter}"> 39 ${letter} : 40 ${currentQuestion.answers[letter]} 41 </label>` 42 ); 43 } 44 45 // add this question and its answers to the output 46 output.push( 47 `<div class="slide"> 48 <div class="question"> ${currentQuestion.question} </div> 49 <div class="answers"> ${answers.join("")} </div> 50 </div>` 51 ); 52 }); 53 54 // finally combine our output list into one string of HTML and put it on the page 55 quizContainer.innerHTML = output.join(""); 56 } 57 58 function showResults() { 59 // gather answer containers from our quiz 60 const answerContainers = quizContainer.querySelectorAll(".answers"); 61 62 // keep track of user's answers 63 let numCorrect = 0; 64 65 // for each question... 66 myQuestions.forEach((currentQuestion, questionNumber) => { 67 // find selected answer 68 const answerContainer = answerContainers[questionNumber]; 69 const selector = `input[name=question${questionNumber}]:checked`; 70 const userAnswer = (answerContainer.querySelector(selector) || {}).value; 71 72 // if answer is correct 73 if (userAnswer === currentQuestion.correctAnswer) { 74 // add to the number of correct answers 75 numCorrect++; 76 77 // color the answers green 78 answerContainers[questionNumber].style.color = "lightgreen"; 79 } else { 80 // if answer is wrong or blank 81 // color the answers red 82 answerContainers[questionNumber].style.color = "red"; 83 } 84 }); 85 86 // show number of correct answers out of total 87 resultsContainer.innerHTML = `${numCorrect} out of ${myQuestions.length}`; 88 } 89 90 function showSlide(n) { 91 slides[currentSlide].classList.remove("active-slide"); 92 slides[n].classList.add("active-slide"); 93 currentSlide = n; 94 95 if (currentSlide === 0) { 96 previousButton.style.display = "none"; 97 } else { 98 previousButton.style.display = "inline-block"; 99 } 100 101 if (currentSlide === slides.length - 1) { 102 nextButton.style.display = "none"; 103 submitButton.style.display = "inline-block"; 104 } else { 105 nextButton.style.display = "inline-block"; 106 submitButton.style.display = "none"; 107 } 108 } 109 110 function showNextSlide() { 111 showSlide(currentSlide + 1); 112 } 113 114 function showPreviousSlide() { 115 showSlide(currentSlide - 1); 116 } 117 118 const quizContainer = document.getElementById("quiz"); 119 const resultsContainer = document.getElementById("results"); 120 const submitButton = document.getElementById("submit"); 121 122 // display quiz right away 123 buildQuiz(); 124 125 const previousButton = document.getElementById("previous"); 126 const nextButton = document.getElementById("next"); 127 const slides = document.querySelectorAll(".slide"); 128 let currentSlide = 0; 129 130 showSlide(0); 131 132 // on submit, show results 133 submitButton.addEventListener("click", showResults); 134 previousButton.addEventListener("click", showPreviousSlide); 135 nextButton.addEventListener("click", showNextSlide); 136})();
json
1[ 2 { 3 "question": "Who is the strongest?", 4 "answers": { 5 "a": "Superman", 6 "b": "The Terminator", 7 "c": "Waluigi, obviously" 8 }, 9 "correctAnswer": "c" 10 }, 11 { 12 "question": "What is the best site ever created?", 13 "answers": { 14 "a": "SitePoint", 15 "b": "Simple Steps Code", 16 "c": "Trick question; they're both the best" 17 }, 18 "correctAnswer": "c" 19 }, 20 { 21 "question": "Where is Waldo really?", 22 "answers": { 23 "a": "Antarctica", 24 "b": "Exploring the Pacific Ocean", 25 "c": "Sitting in a tree", 26 "d": "Minding his own business, so stop asking" 27 }, 28 "correctAnswer": "d" 29 } 30]
HTML
1<!DOCTYPE html> 2<html> 3<head> 4<meta http-equiv="content-type" charset="UTF-8"> 5<link rel="stylesheet" href="css/teraQuizApp.css"> 6<script src="../script/jquery-3.3.1.min.js"></script> 7<title>QuizApp</title> 8</head> 9<body> 10<h1>Quiz</h1> 11<div class="quiz-container"> 12 <div id="quiz"></div> 13</div> 14<button id="previous">前の問題</button> 15<button id="next">次の問題</button> 16<button id="submit">解答を送信</button> 17<div id="results"></div> 18</body> 19<script src="../script/quizScript.js"></script> 20</html>
CSS
1@import url(https://fonts.googleapis.com/css?family=Work+Sans:300,600); 2 3body{ 4 font-size: 20px; 5 font-family: 'Work Sans', sans-serif; 6 color: #333; 7 font-weight: 300; 8 text-align: center; 9 background-color: #f8f6f0; 10} 11h1{ 12 font-weight: 300; 13 margin: 0px; 14 padding: 10px; 15 font-size: 20px; 16 background-color: #444; 17 color: #fff; 18} 19.question{ 20 font-size: 30px; 21 margin-bottom: 10px; 22} 23.answers { 24 margin-bottom: 20px; 25 text-align: left; 26 display: inline-block; 27} 28.answers label{ 29 display: block; 30 margin-bottom: 10px; 31} 32button.start{ 33 padding: 20px; 34} 35button{ 36 font-family: 'Work Sans', sans-serif; 37 font-size: 22px; 38 background-color: #279; 39 color: #fff; 40 border: 0px; 41 border-radius: 3px; 42 padding: 20px; 43 cursor: pointer; 44 margin-bottom: 20px; 45} 46button:hover{ 47 background-color: #38a; 48} 49.slide{ 50 position: absolute; 51 left: 0px; 52 top: 0px; 53 width: 100%; 54 z-index: 1; 55 opacity: 0; 56 transition: opacity 0.5s; 57} 58.active-slide{ 59 opacity: 1; 60 z-index: 2; 61} 62.quiz-container{ 63 position: relative; 64 height: 200px; 65 margin-top: 40px; 66} 67
試したこと
Chromeのデバッカーを用いて、ソースを追ってみました。
結果根本原因はmyQuestionsの中にデータがうまく入っておらず、
エラーが出ているということはわかりました。
JSコードのbuildQuiz()内でjsonLoader()は正常に呼び出されており、
jsonLoader()内で取得後、ループを回してpushし、
抜けた後のconsole.log(myQuestions);ではコンソール内に
(3) [{…}, {…}, {…}]0: {question: "Who is the strongest?", answers: {…}, correctAnswer: "c"}1: {question: "What is the best site ever created?", answers: {…}, correctAnswer: "c"}2: {question: "Where is Waldo really?", answers: {…}, correctAnswer: "d"}length: 3__proto__: Array(0)
というように値は入っているように思われますが、jsonLoader()実行後に
console.log(myQuestions);をすると以下のようになってしまいます。
[]
length: 0
proto: Array(0)
補足情報(FW/ツールのバージョンなど)
HTML5/jQuery3.3.1/Chrome 70.0.3538.77
Chromeは--allow-file-access-from-filesパラメータ付きで起動しています。

回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/05 00:19 編集
2018/11/05 01:31 編集
2018/11/05 02:01