Issue
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>
Solution
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>
Answered By – Marii
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0