I am creating a quiz. My quiz is divided in 4 parts and I have 50 questions total. There is a score and question counter, but I want to continue the question counter and score when the quiz jumped to the next part and I need a total score at the end. I am not expert in Javascript. I am just a beginner. So Please help me with the solution.
const choices = Array.from(document.getElementsByClassName("choice-text"));
const progressText = document.getElementById("progressText");
const scoreText = document.getElementById("score");
const progressBarFull = document.getElementById("progressBarFull");
let currentQuestion = {};
let acceptingAnswers = false;
let score = 0;
let questionCounter = 0;
let availableQuesions = [];
let questions = [
{
question: "Inside which HTML element do we put the JavaScript??",
choice1: "<script>",
choice2: "<javascript>",
choice3: "<js>",
choice4: "<scripting>",
answer: 1
},
{
question:
"What is the correct syntax for referring to an external script called 'xxx.js'?",
choice1: "<script href='xxx.js'>",
choice2: "<script name='xxx.js'>",
choice3: "<script src='xxx.js'>",
choice4: "<script file='xxx.js'>",
answer: 3
},
{
question: " How do you write 'Hello World' in an alert box?",
choice1: "msgBox('Hello World');",
choice2: "alertBox('Hello World');",
choice3: "msg('Hello World');",
choice4: "alert('Hello World');",
answer: 4
}
];
//CONSTANTS
const CORRECT_BONUS = 10;
const MAX_QUESTIONS = 3;
startGame = () => {
questionCounter = 0;
score = 0;
availableQuesions = [...questions];
getNewQuestion();
};
getNewQuestion = () => {
if (availableQuesions.length === 0 || questionCounter >= MAX_QUESTIONS) {
localStorage.setItem("mostRecentScore", score);
//go to the end page
return window.location.assign("/end.html");
}
questionCounter++;
progressText.innerText = `Question ${questionCounter}/${MAX_QUESTIONS}`;
//Update the progress bar
progressBarFull.style.width = `${(questionCounter / MAX_QUESTIONS) * 100}%`;
const questionIndex = Math.floor(Math.random() * availableQuesions.length);
currentQuestion = availableQuesions[questionIndex];
question.innerText = currentQuestion.question;
choices.forEach(choice => {
const number = choice.dataset["number"];
choice.innerText = currentQuestion["choice" + number];
});
availableQuesions.splice(questionIndex, 1);
acceptingAnswers = true;
};
choices.forEach(choice => {
choice.addEventListener("click", e => {
if (!acceptingAnswers) return;
acceptingAnswers = false;
const selectedChoice = e.target;
const selectedAnswer = selectedChoice.dataset["number"];
const classToApply =
selectedAnswer == currentQuestion.answer ? "correct" : "incorrect";
if (classToApply === "correct") {
incrementScore(CORRECT_BONUS);
}
selectedChoice.parentElement.classList.add(classToApply);
setTimeout(() => {
selectedChoice.parentElement.classList.remove(classToApply);
getNewQuestion();
}, 1000);
});
});
incrementScore = num => {
score += num;
scoreText.innerText = score;
};
startGame();
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Quick Quiz - Play</title>
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="game.css" />
</head>
<body>
<div class="container">
<div id="game" class="justify-center flex-column">
<div id="hud">
<div id="hud-item">
<p id="progressText" class="hud-prefix">
Question
</p>
<div id="progressBar">
<div id="progressBarFull"></div>
</div>
</div>
<div id="hud-item">
<p class="hud-prefix">
Score
</p>
<h1 class="hud-main-text" id="score">
0
</h1>
</div>
</div>
<h2 id="question">What is the answer to this questions?</h2>
<div class="choice-container">
<p class="choice-prefix">A</p>
<p class="choice-text" data-number="1">Choice 1</p>
</div>
<div class="choice-container">
<p class="choice-prefix">B</p>
<p class="choice-text" data-number="2">Choice 2</p>
</div>
<div class="choice-container">
<p class="choice-prefix">C</p>
<p class="choice-text" data-number="3">Choice 3</p>
</div>
<div class="choice-container">
<p class="choice-prefix">D</p>
<p class="choice-text" data-number="4">Choice 4</p>
</div>
</div>
</div>
<script src="game.js"></script>
</body>
</html>
If your quiz contains or lasts throughout multiple pages and you want to communicate between those pages then you can use localStorage
When you're done with one part of the quiz, or even if you're not, just set the value of localStorage to the score, and read it on page load, or in general
incrementScore = num => {
if(typeof(localStorage.getItem("score") != "number"))
localStorage.setItem("score", 0)
score = localStorage.getItem("score")
score += num;
scoreText.innerText = score;
};
Related
I am building a simple quiz with JavaScript, when the game starts everything works fine timer counts down, the score and questions both receive the correct values, but when the last question is answered the game will not end until the timer hits 0. I have moved where the timer starts and the game ends when time hits zero still to no success.
please check out the deployed page for a better view of the issue.
https://brycebann.github.io/The-Coding-Quiz/
//calling in id/class from HTML
const questionEl = document.getElementById("question")
const checkers = document.getElementById("right-wrong")
const timerEl = document.getElementsByClassName("timeSpan")
const answerOne = document.getElementById("answer1")
const answerTwo = document.getElementById("answer2")
const answerThree = document.getElementById("answer3")
const answerFour = document.getElementById("answer4")
const finalScoreEl = document.getElementById("pointScore")
const nameEl = document.getElementById("initials")
const highScoreEl = document.getElementById("highScoreList")
//const randomQuestionMix = mixedQ(); comment out to address later
//test question
var questionKey = [
{
question: "which variable has the value of a string.",
choiceOne: "x = 6",
choiceTwo: "x = \"87\"",
choiceThree: "x = true",
choiceFour: "x;",
answer: "x = \"87\""
},
{
question: "choose the operator that checks for value and type.",
choiceOne: "=",
choiceTwo: "+=",
choiceThree: "===",
choiceFour: "<=;",
answer: "==="
},
{
question: "choose the true statement.",
choiceOne: "4 != 4",
choiceTwo: "4 > 85",
choiceThree: "7 === \"7\"",
choiceFour: "7.6 == \"7.6\"",
answer: "7.6 == \"7.6\""
},
{
question: "which data type is not primitive.",
choiceOne: "boolean",
choiceTwo: "array",
choiceThree: "number",
choiceFour: "string",
answer: "array"
},
{
question: "Which one is the Increment operator.",
choiceOne: "**",
choiceTwo: "/",
choiceThree: "++",
choiceFour: "+=",
answer: "++"
}
];
//starting positions
let timeLeft = 60;
let score = 0;
let currentQuestion = -1
let finalScore;
//change div to start the test
function changeDiv(curr, next) {
document.getElementById(curr).classList.add('hide');
document.getElementById(next).removeAttribute('class')
};
//button to start the game, this button will start the functions to change the on screen div and start the count down timer
document.querySelector('#startButton').addEventListener('click', gameStart);
function gameStart() {
changeDiv('start', 'questionHolder');
currentQuestion = 0;
displayQuestion();
startTimer();
};
//timer function/Count down
function startTimer() {
let timeInterval = setInterval(
() => {
timeLeft--;
document.getElementById("timeSpan").innerHTML = timeLeft
if (timeLeft <= 0) {
clearInterval(timeInterval);
gameOver();
}
}, 1000);
};
function displayQuestion() {
questionEl.textContent = questionKey[currentQuestion].question
answerOne.textContent = questionKey[currentQuestion].choiceOne
answerTwo.textContent = questionKey[currentQuestion].choiceTwo
answerThree.textContent = questionKey[currentQuestion].choiceThree
answerFour.textContent = questionKey[currentQuestion].choiceFour
}
//will end game when all questions are completed as well as populate the next question
document.querySelector('#questionHolder').addEventListener('click', nextquestion);
function nextquestion(event) {
//console.log(event)
//console.log(event.target.className)
//console.log(event.target.textContent)
if (event.target.className === "btn") {
console.log(event.target.textContent, questionKey[currentQuestion].answer)
if (event.target.textContent === questionKey[currentQuestion].answer) {
score += 10
console.log("correct")
console.log(score)
} else {
if (timeLeft >= 10) {
console.log(timeLeft)
timeLeft = timeLeft - 10;
document.getElementById("timeSpan").innerHTML = timeLeft
console.log("not correct")
} else {
timeLeft = 0;
gameOver();
}
}
currentQuestion++;
displayQuestion();
}
};
//the game is over and logs your current score
function gameOver() {
timerEl.textContent = 0;
changeDiv('questionHolder', 'finishedPage');
finalScore = score;
finalScoreEl.textContent = finalScore;
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The coding quiz</title>
<link rel="stylesheet" a href="./Main/style.css">
</head>
<body>
<!--Top of page-->
<header>
<div id="pageTop">
<h1>The coding quiz</h1>
</div>
</header>
<!--High score and timer div -->
<div id="scoreTime">
<p class="highscore">View highscores</p>
<p class="timer">Time left: <span id="timeSpan">60</span></p>
</div>
<!--Main quiz portion of the page-->
<div id="quizHolder">
<div id="start">
<h2>Basic Code Quiz</h2>
<p>Welcome to the basic coding quiz, this quiz will test you knoweledge on basic javascript.</p>
<button id="startButton" class="btn">Start</button>
</div>
<div id="questionHolder" class="hide">
<h2 id="question"></h2>
<button id="answer1" class="btn"></button>
<button id="answer2" class="btn"></button>
<button id="answer3" class="btn"></button>
<button id="answer4" class="btn"></button>
</div>
<!--Results and high score-->
<div id="finishedPage" class="hide">
<h2>Quiz Complete</h2>
<p>Your final score is <span id="pointScore"></span>/50</p>
<label>Enter your initials:</label>
<input type="text" id="initials">
<button id="sendScore" class="btn">Submit score</button>
</div>
</div>
<script src="Main/script.js"></script>
</body>
</html>
After you increment the "current question" counter, here currentQuestion++; check if the counter reached the length of your questions array questionKey:
// IF THERE ARE NO MORE QUESTIONS, CALL gameOver
if (currentQuestion == questionKey.length) {
gameOver();
} else {
displayQuestion();
}
//calling in id/class from HTML
const questionEl = document.getElementById("question")
const checkers = document.getElementById("right-wrong")
const timerEl = document.getElementsByClassName("timeSpan")
const answerOne = document.getElementById("answer1")
const answerTwo = document.getElementById("answer2")
const answerThree = document.getElementById("answer3")
const answerFour = document.getElementById("answer4")
const finalScoreEl = document.getElementById("pointScore")
const nameEl = document.getElementById("initials")
const highScoreEl = document.getElementById("highScoreList")
//const randomQuestionMix = mixedQ(); comment out to address later
//test question
var questionKey = [
{
question: "which variable has the value of a string.",
choiceOne: "x = 6",
choiceTwo: "x = \"87\"",
choiceThree: "x = true",
choiceFour: "x;",
answer: "x = \"87\""
},
{
question: "choose the operator that checks for value and type.",
choiceOne: "=",
choiceTwo: "+=",
choiceThree: "===",
choiceFour: "<=;",
answer: "==="
},
{
question: "choose the true statment.",
choiceOne: "4 != 4",
choiceTwo: "4 > 85",
choiceThree: "7 === \"7\"",
choiceFour: "7.6 == \"7.6\"",
answer: "7.6 == \"7.6\""
},
{
question: "which data type is not primitive.",
choiceOne: "boolean",
choiceTwo: "array",
choiceThree: "number",
choiceFour: "string",
answer: "array"
},
{
question: "Wich one is the Increment operator.",
choiceOne: "**",
choiceTwo: "/",
choiceThree: "++",
choiceFour: "+=",
answer: "++"
}
];
//starting postions
let timeLeft = 60;
let score = 0;
let currentQuestion = -1
let finalScore;
let timeInterval;
//change div to start the test
function changeDiv(curr, next) {
document.getElementById(curr).classList.add('hide');
document.getElementById(next).removeAttribute('class')
};
//button to start the game, this button will start the functions to cnage the on screen div and start the count down timer
document.querySelector('#startButton').addEventListener('click', gameStart);
function gameStart() {
changeDiv('start', 'questionHolder');
currentQuestion = 0;
displayQuestion();
startTimer();
};
//timer function/Count down
function startTimer() {
timeInterval = setInterval(
() => {
timeLeft--;
document.getElementById("timeSpan").innerHTML = timeLeft
if (timeLeft <= 0) {
clearInterval(timeInterval);
gameOver();
}
}, 1000);
};
function displayQuestion() {
questionEl.textContent = questionKey[currentQuestion].question
answerOne.textContent = questionKey[currentQuestion].choiceOne
answerTwo.textContent = questionKey[currentQuestion].choiceTwo
answerThree.textContent = questionKey[currentQuestion].choiceThree
answerFour.textContent = questionKey[currentQuestion].choiceFour
}
//will end game when all questions are completed as well as populate the next question
document.querySelector('#questionHolder').addEventListener('click', nextquestion);
function nextquestion(event) {
//console.log(event)
//console.log(event.target.className)
//console.log(event.target.textContent)
if (event.target.className === "btn") {
console.log(event.target.textContent, questionKey[currentQuestion].answer)
if (event.target.textContent === questionKey[currentQuestion].answer) {
score += 10
console.log("correct")
console.log(score)
} else {
if (timeLeft >= 10) {
console.log(timeLeft)
timeLeft = timeLeft - 10;
document.getElementById("timeSpan").innerHTML = timeLeft
console.log("not correct")
} else {
timeLeft = 0;
gameOver();
}
}
currentQuestion++;
// IF THERE ARE NO MORE QUESTIONS, CALL gameOver
if (currentQuestion == questionKey.length) {
clearInterval(timeInterval);
gameOver();
} else {
displayQuestion();
}
}
};
//the game is over and logs your current score
function gameOver() {
timerEl.textContent = 0;
changeDiv('questionHolder', 'finishedPage');
finalScore = score;
finalScoreEl.textContent = finalScore;
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The coding quiz</title>
<link rel="stylesheet" a href="./Main/style.css">
</head>
<body>
<!--Top of page-->
<header>
<div id="pageTop">
<h1>The coding quiz</h1>
</div>
</header>
<!--High score and timer div -->
<div id="scoreTime">
<p class="highscore">View highscores</p>
<p class="timer">Time left: <span id="timeSpan">60</span></p>
</div>
<!--Main quiz portion of the page-->
<div id="quizHolder">
<div id="start">
<h2>Basic Code Quiz</h2>
<p>Welcome to the basic coding quiz, this quiz will test you knoweledge on basic javascript.</p>
<button id="startButton" class="btn">Start</button>
</div>
<div id="questionHolder" class="hide">
<h2 id="question"></h2>
<button id="answer1" class="btn"></button>
<button id="answer2" class="btn"></button>
<button id="answer3" class="btn"></button>
<button id="answer4" class="btn"></button>
</div>
<!--Results and high score-->
<div id="finishedPage" class="hide">
<h2>Quiz Complete</h2>
<p>Your final score is <span id="pointScore"></span>/50</p>
<label>Enter your initials:</label>
<input type="text" id="initials">
<button id="sendScore" class="btn">Submit score</button>
</div>
</div>
<script src="Main/script.js"></script>
</body>
</html>
I am developing a simple quiz using Javascript, HTML5 and CSS3.
Currently, when a user selects an answer, it proceeds to the next question regardless of whether the answer is correct or not.
I want to enable multiple attempts for the users. If the user selects the wrong option, that option will be marked red while giving the user another chance to select another option (like elimination process). The next question will only be shown until the user selects the correct answer.
Here are my codes:
game.js
const question = document.querySelector('#question'); //can target both the class and the ID
const choices = Array.from(document.querySelectorAll('.choice-text'));
const scoreText = document.querySelector('#score');
let currentQuestion = {}
let acceptingAnswers = true
let score = 0
let questionCounter = 0
let availableQuestions = []
let questions = [
{
question: 'What is 2 + 2?',
choice1: '5',
choice2: '10',
choice3: '1',
choice4: '4',
answer: 4
},
{
question: 'When is Christmas?',
choice1: '25 December',
choice2: '1 January',
choice3: '4 July',
choice4: '30 October',
answer: 1
},
{
question: 'What is the capital of Japan?',
choice1: 'Seoul',
choice2: 'Beijing',
choice3: 'Tokyo',
choice4: 'Washington D.C.',
answer: 3
},
{
question: 'What is the emergency number?',
choice1: '123',
choice2: '555',
choice3: '420',
choice4: '911',
answer: 4
}
]
const SCORE_POINTS = 10
const MAX_QUESTIONS = 4
startGame = () =>{
questionCounter = 0
score = 0
availableQuestions = [...questions]
getNewQuestion()
}
getNewQuestion = () => {
if(availableQuestions.length === 0 || questionCounter > MAX_QUESTIONS) {
localStorage.setItem('mostRecentScore', score)
return window.location.assign('end.html')
}
questionCounter++
const questionsIndex = Math.floor(Math.random() * availableQuestions.length)
currentQuestion = availableQuestions[questionsIndex]
question.innerText = currentQuestion.question
choices.forEach(choice => {
const number = choice.dataset['number']
choice.innerText= currentQuestion['choice' + number]
})
availableQuestions.splice(questionsIndex, 1)
acceptingAnswers = true
}
choices.forEach(choice => {
choice.addEventListener('click', e => {
if(!acceptingAnswers) return
acceptingAnswers = false
const selectedChoice = e.target
const selectedAnswer = selectedChoice.dataset['number']
let classToApply = selectedAnswer == currentQuestion.answer ? 'correct' : 'incorrect'
if(classToApply === 'correct') {
incrementScore(SCORE_POINTS)
}
selectedChoice.parentElement.classList.add(classToApply)
setTimeout(() => {
selectedChoice.parentElement.classList.remove(classToApply)
getNewQuestion()
}, 500)
})
})
incrementScore = num => {
score += num
scoreText.innerText = score
}
startGame()
game.html
<!DOCTYPE html>
<html>
<head>
<title>Trivia Quiz</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="style.css" rel="stylesheet">
<link href="game.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div id="game" class="justify-center flex-column">
<div id="hud">
<div class="hud-item">
<p id="gameTitle" class="hud-prefix">
Trivia Quiz
</p>
<p id="quizMode" class="hud-prefix2">
<br>Normal Mode
</p>
</div>
<div class="hud-item">
<p id= "gamePoints" class="hud-prefix">
Points
</p>
<h1 class="hud-main-text" id="score">
0
</h1>
</div>
</div>
<h1 id="question">What is the answer?</h1>
<div class="choice-container">
<p class="choice-text" data-number="1">A</p>
</div>
<div class="choice-container">
<p class="choice-text" data-number="2">B</p>
</div>
<div class="choice-container">
<p class="choice-text" data-number="3">C</p>
</div>
<div class="choice-container">
<p class="choice-text" data-number="4">D</p>
</div>
</div>
</div>
<script src="game.js"></script>
</body>
</html>
Try this
const question = document.querySelector('#question'); //can target both the class and the ID
const choices = Array.from(document.querySelectorAll('.choice-text'));
const scoreText = document.querySelector('#score');
let currentQuestion = {}
let acceptingAnswers = true
let score = 0
let questionCounter = 0
let availableQuestions = []
let questions = [
{
question: 'What is 2 + 2?',
choice1: '5',
choice2: '10',
choice3: '1',
choice4: '4',
answer: 4
},
{
question: 'When is Christmas?',
choice1: '25 December',
choice2: '1 January',
choice3: '4 July',
choice4: '30 October',
answer: 1
},
{
question: 'What is the capital of Japan?',
choice1: 'Seoul',
choice2: 'Beijing',
choice3: 'Tokyo',
choice4: 'Washington D.C.',
answer: 3
},
{
question: 'What is the emergency number?',
choice1: '123',
choice2: '555',
choice3: '420',
choice4: '911',
answer: 4
}
]
const SCORE_POINTS = 10
const MAX_QUESTIONS = 4
startGame = () =>{
questionCounter = 0
score = 0
availableQuestions = [...questions]
getNewQuestion()
}
getNewQuestion = () => {
if(availableQuestions.length === 0 || questionCounter > MAX_QUESTIONS) {
localStorage.setItem('mostRecentScore', score)
return window.location.assign('end.html')
}
let container = document.getElementsByClassName('choice-container');
for(var i = 0; i < container.length; i++)
{
container[i].classList.remove('error', 'incorrect', 'correct');
}
questionCounter++
const questionsIndex = Math.floor(Math.random() * availableQuestions.length)
currentQuestion = availableQuestions[questionsIndex]
question.innerText = currentQuestion.question
choices.forEach(choice => {
const number = choice.dataset['number']
choice.innerText= currentQuestion['choice' + number]
})
availableQuestions.splice(questionsIndex, 1)
acceptingAnswers = true
}
for (i = 0; i < choices.length; i++) {
choices[i].addEventListener('click', e => {
// if(!acceptingAnswers) return
acceptingAnswers = false
const selectedChoice = e.target
const selectedAnswer = selectedChoice.dataset['number']
let classToApply = selectedAnswer == currentQuestion.answer ? 'correct' : 'incorrect'
if(classToApply === 'correct') {
incrementScore(SCORE_POINTS)
setTimeout(() => {
selectedChoice.parentElement.classList.remove(classToApply)
getNewQuestion()
}, 500)
} else {
selectedChoice.parentElement.classList.add("error")
}
selectedChoice.parentElement.classList.add(classToApply)
})
}
incrementScore = num => {
score += num
scoreText.innerText = score
}
startGame()
.error {
color: red;
}
<!DOCTYPE html>
<html>
<head>
<title>Trivia Quiz</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="style.css" rel="stylesheet">
<link href="game.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div id="game" class="justify-center flex-column">
<div id="hud">
<div class="hud-item">
<p id="gameTitle" class="hud-prefix">
Trivia Quiz
</p>
<p id="quizMode" class="hud-prefix2">
<br>Normal Mode
</p>
</div>
<div class="hud-item">
<p id= "gamePoints" class="hud-prefix">
Points
</p>
<h1 class="hud-main-text" id="score">
0
</h1>
</div>
</div>
<h1 id="question">What is the answer?</h1>
<div class="choice-container">
<p class="choice-text" data-number="1">A</p>
</div>
<div class="choice-container">
<p class="choice-text" data-number="2">B</p>
</div>
<div class="choice-container">
<p class="choice-text" data-number="3">C</p>
</div>
<div class="choice-container">
<p class="choice-text" data-number="4">D</p>
</div>
</div>
</div>
<script src="game.js"></script>
</body>
</html>
I created an array of objects with different properties but I am having problem displaying each properties of my object on the webpage. I have tried but I don't know where the problem is.
I have tried to access the objects individually but still not working please check the problem
//Get the id's of all elements
const intro = document.getElementById("introduction");
const continued = document.getElementById("continue");
const name = document.getElementById("name").value;
const wel = document.getElementById("wel")
const startt = document.getElementById("startt");
const start = document.getElementById("start");
const quiz = document.getElementById("quiz");
const question = document.getElementById("question");
const qImg = document.getElementById("qImg");
const choiceA = document.getElementById("A");
const choiceB = document.getElementById("B");
const choiceC = document.getElementById("C");
const choiceD = document.getElementById("D");
const counter = document.getElementById("counter");
const timeGauge = document.getElementById("timeGauge");
const progress = document.getElementById("progress");
const scoreDiv = document.getElementById("scoreContainer");
//Event listeners
continued.addEventListener('click', continueAfterIntro);
start.addEventListener('click', startQuiz);
//variable declarations
const lastQuestion = questions.length - 1;
var runningQuestion = 0;
var secs = 0;
var mins = 0;
var hrs = 0;
const questionTime = 60; // 60s
const gaugeWidth = 180; // 180px
const gaugeUnit = gaugeWidth / questionTime;
let TIMER;
let score = 0;
//Array object declaration
let questions = [{
question: "Who is the president Nigeria?",
choiceA: "Muhamadu Buhari",
choiceB: "Osibajo",
choiceC: "Obasanjo",
choiceD: "Green,Red,Green",
correct: "A"
}, {
question: "Who is the governor of oyo state?",
choiceA: "Abiola Ajumobi",
choiceB: "Seyi makinde",
choiceC: "Alao Akala",
choiceD: "Green,Red,Green",
correct: "B"
}, {
question: "What are the colors of the Nigerian Flag?",
choiceA: "Green,White,Blue",
choiceB: "Blue,White,Green",
choiceC: "Green,White,Green",
choiceD: "Green,Red,Green",
correct: "C"
}];
function continueAfterIntro() {
intro.style.display = 'none';
startt.style.display = 'block';
wel.innerHTML = `Hi ${name}`;
}
function renderQuestion() {
let q = questions[runningQuestion];
question.innerHTML = "<p>" + q.question + "</p>";
choiceA.innerHTML = q.choiceA;
choiceB.innerHTML = q.choiceB;
choiceC.innerHTML = q.choiceC;
}
function startQuiz() {
startt.style.display = "none";
quiz.style.display = "block";
renderQuestion();
}
<div id="container">
<div class="" id="introduction">
<div id="pimg"><img src="pic/thumbs.png" alt="WELCOME FACE"></div>
<div id="para1">
<p>Hey there i'm AFO by name whats yours</p>
</div>
<div id="name-button">
<span id="iName"><input type="text" id="name" placeholder="Type Your Name Here"></span>
<span id="continue"><input type="button" value="Continue" id="continue"></span>
</div>
</div>
<div id="startt" style="display: none">
<p id="wel"></p>
<div id="start">Start Quiz!</div>
</div>
<div id="quiz" style="display: none">
<div id="question"></div>
<div id="choices">
A.
<div class="choice" id="A" onclick="checkAnswer('A')"></div>
B.
<div class="choice" id="B" onclick="checkAnswer('B')"></div>
C.
<div class="choice" id="C" onclick="checkAnswer('C')"></div>
D.
<div class="choice" id="D" onclick="checkAnswer('D')"></div>
</div>
<div id="timer">
<div id="counter"></div>
<div id="btimeGauge"></div>
<div id="timeGauge"></div>
</div>
<div id="progress"></div>
</div>
<div id="scoreContainer" style="display: none"></div>
</div>
The function renderQuestion should display the questions and the choices on the webpage
When i run your project i got ReferenceError.
Uncaught ReferenceError: Cannot access 'questions' before initialization
That means you can't play around with Questions Array before initialization. For example:
const questionsLength = questions.length; // REFERENCE ERROR.
const questions = ['a', 'b', 'c'];
console.log(questionsLength);
Declare Questions Array before you inspect length:
const questions = ['a', 'b', 'c'];
const questionsLength = questions.length;
console.log(questionsLenght) // Returns 3
Working example:
//Get the id's of all elements
const intro = document.getElementById("introduction");
const continued = document.getElementById("continue");
const name = document.getElementById("name").value;
const wel = document.getElementById("wel")
const startt = document.getElementById("startt");
const start = document.getElementById("start");
const quiz = document.getElementById("quiz");
const question = document.getElementById("question");
const qImg = document.getElementById("qImg");
const choiceA = document.getElementById("A");
const choiceB = document.getElementById("B");
const choiceC = document.getElementById("C");
const choiceD = document.getElementById("D");
const counter = document.getElementById("counter");
const timeGauge = document.getElementById("timeGauge");
const progress = document.getElementById("progress");
const scoreDiv = document.getElementById("scoreContainer");
//Event listeners
continued.addEventListener('click',continueAfterIntro);
start.addEventListener('click',startQuiz);
//Array object declaration
let questions = [
{
question : "Who is the president Nigeria?",
choiceA : "Muhamadu Buhari",
choiceB : "Osibajo",
choiceC : "Obasanjo",
choiceD : "Green,Red,Green",
correct : "A"
},{
question : "Who is the governor of oyo state?",
choiceA : "Abiola Ajumobi",
choiceB : "Seyi makinde",
choiceC : "Alao Akala",
choiceD : "Green,Red,Green",
correct : "B"
},{
question : "What are the colors of the Nigerian Flag?",
choiceA : "Green,White,Blue",
choiceB : "Blue,White,Green",
choiceC : "Green,White,Green",
choiceD : "Green,Red,Green",
correct : "C"
}
];
//variable declarations
const lastQuestion = questions.length - 1;
var runningQuestion = 0;
var secs = 0;
var mins = 0;
var hrs = 0;
const questionTime = 60; // 60s
const gaugeWidth = 180; // 180px
const gaugeUnit = gaugeWidth / questionTime;
let TIMER;
let score = 0;
function continueAfterIntro(){
intro.style.display = 'none';
startt.style.display = 'block';
wel.innerHTML = `Hi ${name}`;
}
function renderQuestion(){
let q = questions[runningQuestion];
question.innerHTML = "<p>"+ q.question +"</p>";
choiceA.innerHTML = q.choiceA;
choiceB.innerHTML = q.choiceB;
choiceC.innerHTML = q.choiceC;
}
function startQuiz(){
startt.style.display = "none";
quiz.style.display = "block";
renderQuestion();
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="quiz.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="container">
<div class="" id="introduction">
<div id="pimg"><img src="pic/thumbs.png" alt="WELCOME FACE"></div>
<div id="para1"><p>Hey there i'm AFO by name whats yours</p> </div>
<div id="name-button">
<span id="iName"><input type="text" id="name" placeholder="Type Your Name Here"></span>
<span id="continue"><input type="button" value="Continue" id="continue"></span>
</div>
</div>
<div id="startt" style="display: none">
<p id="wel"></p>
<div id="start" >Start Quiz!</div>
</div>
<div id="quiz" style="display: none">
<div id="question"></div>
<div id="choices">
A.<div class="choice" id="A" onclick="checkAnswer('A')"></div>
B.<div class="choice" id="B" onclick="checkAnswer('B')"></div>
C.<div class="choice" id="C" onclick="checkAnswer('C')"></div>
D.<div class="choice" id="D" onclick="checkAnswer('D')"></div>
</div>
<div id="timer">
<div id="counter"></div>
<div id="btimeGauge"></div>
<div id="timeGauge"></div>
</div>
<div id="progress"></div>
</div>
<div id="scoreContainer" style="display: none"></div>
</div>
</body>
</html>
What ReferenceError mean MDN#ReferenceError
I am going through this JavaScript tutorial and ran into an issue that I hope someone can assist me with. After selecting the last question on the quiz, my showScore() function displays the results as "undefined". Through some further debugging, I found that it was a problem with my quiz object. In my PopulateQuestion() function, I am able to print out the quiz object before executing the showScore() function. However, when I attempt to print out the quiz object from within the showScore() function, it returns undefined.
I would like to work on my ability to debug issues that come up like this. Based on debugging that I have done so far, my educated guess is that this is a scope issue, but I am stuck. Does anyone have any suggestions for debugging this further?
Here is my code
Index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>JS Quiz</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="quiz-container">
<div id="quiz">
<h1>Star Wars Quiz</h1>
<hr style="margin-top: 20px;" />
<p id="question">Who is Darth Vader?</p>
<div class="buttons">
<button id="b0"><span id="c0"></span></button>
<button id="b1"><span id="c1"></span></button>
<button id="b2"><span id="c2"></span></button>
<button id="b3"><span id="c3"></span></button>
</div>
<hr style="margin-top: 50px" />
<footer>
<p id="progress">Question x of n</p>
</footer>
</div>
</div>
<script src="quiz-controller.js"></script>
<script src="question.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js
function populateQuestion() {
if(quiz.isEnded()) {
// display score
console.log(quiz);
showScore();
} else {
// display question
var qElement = document.getElementById('question');
qElement.innerHTML = quiz.getCurrentQuestion().text;
// display choices
var choices = quiz.getCurrentQuestion().choices;
for(var i = 0; i < choices.length; i++) {
var choice = document.getElementById('c' + i);
choice.innerHTML = choices[i];
guess("b" + i, choices[i]);
}
showProgress();
}
}
function guess(id, guess) {
var button = document.getElementById(id);
button.onclick = function() {
quiz.guess(guess);
populateQuestion();
};
}
function showProgress() {
var currentQuestionNum = quiz.questionIndex + 1;
var progress = document.getElementById("progress");
progress.innerHTML = "Question " + currentQuestionNum + " of " + quiz.questions.length;
}
function showScore() {
console.log(quiz);
var resultsHTML = "<h1>Results</h1>";
resultsHTML += "<h2 id='score'>Your Score: " + quiz.getScore() + "</h2>";
var quiz = document.getElementById("quiz");
quiz.innerHTML = resultsHTML;
}
var questions = [
new Question("Who is Darth Vader?",
["Luke Skywalker", "Anakin Skywalker", "Your Mom", "Your Dad"],
"Anakin Skywalker"),
new Question("What is the name of the third episode?",
["Return of the Jedi", "Revenge of the Sith", "A New Hope", "The Empire Strikes Back"],
"Revenge of the Sith"),
new Question("Who is Anakin Skywalker's son?",
["Luke Skywalker", "Anakin Skywalker", "Your Mom", "Your Dad"],
"Luke Skywalker"),
new Question("What is the name of the sixth episode?",
["Return of the Jedi", "Revenge of the Sith", "A New Hope", "The Empire Strikes Back"],
"Return of the Jedi")
];
var quiz = new Quiz(questions);
populateQuestion();
question.js
function Question(text, choices, answer) {
this.text = text;
this.choices = choices;
this.answer = answer;
}
Question.prototype.correctAnswer = function(choice) {
return choice === this.answer;
};
quiz-controller.js
function Quiz(questions) {
this.score = 0;
this.questionIndex = 0;
this.questions = questions;
}
Quiz.prototype.getScore = function() {
return this.score;
};
Quiz.prototype.getCurrentQuestion = function() {
return this.questions[this.questionIndex];
};
Quiz.prototype.isEnded = function() {
return this.questionIndex === this.questions.length;
};
Quiz.prototype.guess = function(answer) {
if(this.getCurrentQuestion().correctAnswer(answer)) {
this.score++;
}
this.questionIndex++;
};
Your problem is that in the showScore() function you define a local variable with the name quiz. This local variable hides the global variable with the same name (even though it is defined later in the code).
You can easily fix that by renaming your local variable in showScore (below shown as q instead of quiz):
function populateQuestion() {
if(quiz.isEnded()) {
// display score
console.log(quiz);
showScore();
} else {
// display question
var qElement = document.getElementById('question');
qElement.innerHTML = quiz.getCurrentQuestion().text;
// display choices
var choices = quiz.getCurrentQuestion().choices;
for(var i = 0; i < choices.length; i++) {
var choice = document.getElementById('c' + i);
choice.innerHTML = choices[i];
guess("b" + i, choices[i]);
}
showProgress();
}
}
function guess(id, guess) {
var button = document.getElementById(id);
button.onclick = function() {
quiz.guess(guess);
populateQuestion();
};
}
function showProgress() {
var currentQuestionNum = quiz.questionIndex + 1;
var progress = document.getElementById("progress");
progress.innerHTML = "Question " + currentQuestionNum + " of " + quiz.questions.length;
}
function showScore() {
console.log(quiz);
var resultsHTML = "<h1>Results</h1>";
resultsHTML += "<h2 id='score'>Your Score: " + quiz.getScore() + "</h2>";
var q = document.getElementById("quiz");
q.innerHTML = resultsHTML;
}
var questions = [
new Question("Who is Darth Vader?",
["Luke Skywalker", "Anakin Skywalker", "Your Mom", "Your Dad"],
"Anakin Skywalker"),
new Question("What is the name of the third episode?",
["Return of the Jedi", "Revenge of the Sith", "A New Hope", "The Empire Strikes Back"],
"Revenge of the Sith"),
new Question("Who is Anakin Skywalker's son?",
["Luke Skywalker", "Anakin Skywalker", "Your Mom", "Your Dad"],
"Luke Skywalker"),
new Question("What is the name of the sixth episode?",
["Return of the Jedi", "Revenge of the Sith", "A New Hope", "The Empire Strikes Back"],
"Return of the Jedi")
];
function Question(text, choices, answer) {
this.text = text;
this.choices = choices;
this.answer = answer;
}
Question.prototype.correctAnswer = function(choice) {
return choice === this.answer;
};
function Quiz(questions) {
this.score = 0;
this.questionIndex = 0;
this.questions = questions;
}
Quiz.prototype.getScore = function() {
return this.score;
};
Quiz.prototype.getCurrentQuestion = function() {
return this.questions[this.questionIndex];
};
Quiz.prototype.isEnded = function() {
return this.questionIndex === this.questions.length;
};
Quiz.prototype.guess = function(answer) {
if(this.getCurrentQuestion().correctAnswer(answer)) {
this.score++;
}
this.questionIndex++;
};
var quiz = new Quiz(questions);
populateQuestion();
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>JS Quiz</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="quiz-container">
<div id="quiz">
<h1>Star Wars Quiz</h1>
<hr style="margin-top: 20px;" />
<p id="question">Who is Darth Vader?</p>
<div class="buttons">
<button id="b0"><span id="c0"></span></button>
<button id="b1"><span id="c1"></span></button>
<button id="b2"><span id="c2"></span></button>
<button id="b3"><span id="c3"></span></button>
</div>
<hr style="margin-top: 50px" />
<footer>
<p id="progress">Question x of n</p>
</footer>
</div>
</div>
<script src="quiz-controller.js"></script>
<script src="question.js"></script>
<script src="app.js"></script>
</body>
</html>
There is private variable quiz in showScore
function which is getting hoisted to the top of the
function as follows:
Your code:
function showScore() {
console.log(quiz);
var resultsHTML = "<h1>Results</h1>";
resultsHTML += "<h2 id='score'>Your Score: " + quiz.getScore() + "</h2>";
var quiz = document.getElementById("quiz");
What internally happens:
function showScore() {
var quiz = undefined; // hoisting is happening here. So quiz is not reffering to public quiz variable anymore.
console.log(quiz);
var resultsHTML = "<h1>Results</h1>";
resultsHTML += "<h2 id='score'>Your Score: " + quiz.getScore() + "</h2>";
var quiz = document.getElementById("quiz");
I am new to the programming world and have been working on a trivia-game style project. The problem I am encountering is as follows: "Uncaught ReferenceError: answer is not defined at HTMLButtonElement.button.onclick".
My question is as follows: How are my question answers not being stored when pressing an answer and what is a better way to define answer in my code? Any help would greatly be appreciated.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Trivia Game</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" />
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css?family=Lora" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="assets/css/style.css" />
</head>
<body>
<div class="grid">
<div id="trivia">
<h1>A Golfer's Trivia</h1>
<!-- for question -->
<div id="questionName">
<p id="question"></p>
</div>
<p id="progress"></p>
<!-- options for the questions -->
<div class="buttons">
<button id="btn0"><span id="option0"></span></button>
<button id="btn1"><span id="option1"></span></button>
<button id="btn2"><span id="option2"></span></button>
<button id="btn3"><span id="option3"></span></button>
</div>
<div>
<p id="timer"></p>
<p id="show-clock"></p>
</div>
</div>
</div>
<script type="text/javascript" src="assets/javascript/game.js"></script>
</body>
</html>``
JAVASCRIPT
// Keeping score
var unanswered = 0;
var questionIndex = 0;
var score = 0;
var questions = 0;
var answer;
function Quiz(questions) {
this.score = 0;
this.questions = questions;
this.questionIndex = 0;
}
function getQuestionIndex() {
return this.questions[this.questionIndex];
}
function endGame() {
return this.questions.length === this.questionIndex;
}
function guess(answer) {
if (this.getQuestionIndex() === correctAnswer(answer)) {
this.score++;
}
this.questionIndex++;
}
// functions for questions
function Question(text, choices, answer) {
this.text = text;
this.choices = choices;
this.answer = answer;
}
// check user answer
function correctAnswer(choice) {
return choice === this.answer;
}
// have questions appear if game is still going
function populate() {
console.log("populating");
if (endGame()) {
showScores();
}
else {
var element = document.getElementById("question");
element.innerHTML = getQuestionIndex().text;
// have options appear for each question
var choices = getQuestionIndex().choices;
for (var i = 0; i < choices.length; i++) {
var element = document.getElementById("option" + i);
element.innerHTML = choices[i];
guess("btn" + i, choices[i]);
}
showProgress()
}
}
// store user guess
function guess(id) {
var button = document.getElementById(id);
button.onclick = function () {
questionIndex++;
populate();
guess(answer);
}
}
// show which question player is on
function showProgress() {
var currentQuestionNumber = questionIndex + 1;
var element = document.getElementById("progress");
element.innerHTML = "Question " + currentQuestionNumber + " of " + questions.length;
}
// display scores at end of game
function showScores() {
var gameOver = "<h1>Results</h1>" + "<h2 class='corr score'> Correct Answers: " + score + "<h2>" + "<br>" + "<h2 class = 'wrong score'>Wrong Answers: " + (questions.length - score) + "<h2 class = 'unanswered score'>Unanswered: " + "<h2>";
var results = document.getElementById("trivia");
results.innerHTML = gameOver;
}
// sets of questions, options, answers
var questions = [
new Question("Where was the game of golf originally founded?",
["Scotland", "China", "England", "United States"],
"Scotland"),
new Question("Who is the only female golfer to make a cut at a PGA Tour event?",
["Michelle Wie", "Annika Sorensteim", "Lexi Thompson", "Babe Zaharias"],
"Babe Zaharias"),
new Question("What is the name for a hole-in-one on a par five?",
["Triple Eagle", "Double Ace", "Condor", "Albatross"],
"Condor"),
new Question("Who holds the record for the most PGA Tour victories?",
["Tiger Woods", "Jack Nicklaus", "Ben Hogan", "Sam Snead"],
"Sam Snead"),
new Question("What percentage of golfers will never achieve a handicap of 18 or less?",
["50 percent", "73 percent", "80 percent", "91 percent"],
"80 percent"),
new Question("How many dimples are on a standard regulation golf ball?",
["336", "402", "196", "468"],
"336"),
new Question("Who was considered the first professional golfer in history?",
["Bobby Jones", "Byron Nelson", "Walter Hagen", "Old Tom Morris"],
"Walter Hagen"),
new Question("Who is the youngest player to win the Masters?",
["Tiger Woods", "Jack Nicklaus", "Jordan Speith", "Arnold Palmer"],
"Tiger Woods")
];
populate();
var intervalId;
$("#btn").on("click", run);
// The run function sets an interval
function run() {
clearInterval(intervalId);
}
var timeLeft = 10;
var displayClock = document.getElementById('timer');
var timerId = setInterval(countdown, 1000);
function countdown() {
if (timeLeft === 0) {
unanswered++;
questionIndex++;
populate();
alert("You did not answer in time!");
timeLeft = 10;
// reset timer, pull question
run();
} else {
displayClock.innerHTML = timeLeft + ' seconds remaining';
timeLeft--;
}
}
run();
I guess you're facing another problem here. Here are 2 functions taken off your script:
guess(any) version 1
function guess(answer) {
if (this.getQuestionIndex() === correctAnswer(answer)) {
this.score++;
}
this.questionIndex++;
}
guess(any)version 2
function guess(id) {
var button = document.getElementById(id);
button.onclick = function () {
questionIndex++;
populate();
guess(answer);
}
}
You have 2 of a function named guess(). Although the names of both values vary, from Javascript's standpoint they both look like this:
function guess(value){}
How is JS supposed to know which of them you intend to call?
Rename at least one of them in order to having total unambiguousness among your function names. And try again.