I am making a quiz website using javascript, and with the help of css I am trying to fill the box with color as the quiz goes on. However the code I am writing is not exactly working. any suggestions? I think the game.js class is unable to find progressBarFull. any sort of help will be appreciated.
//////game.js/////
const question = document.getElementById('question');
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 acceptingAnswer = false;
let Score = 0 ;
let QuestionCounter = 0;
let AvailableQuestion = [];
let questions = [
{
question:"Inside which HTML element do we put JavaScript?",
choice1: "<script>",
choice2: "<javascript>",
choice3: "<js>",
choice4: "<scripting>",
answer: 1
},
{
question:"What is correct syntax for referreing 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 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;
const INCORRECT = 10;
startgame = ( ) =>{
QuestionCounter=0;
Score=0;
AvailableQuestion=[...questions];
console.log(AvailableQuestion);
getNewQuestion();
};
getNewQuestion =()=> {
if(AvailableQuestion.length == 0 || question>= MAX_QUESTIONS){
// Go to the endpage
return window.location.assign('/end.html');
}
QuestionCounter ;
progressText.innerText = `Question ${QuestionCounter} / ${MAX_QUESTIONS}`;
// Update The ProgressBar
progressBarFull.style.width = `${(QuestionCounter / MAX_QUESTIONS) * 100}
%`
console.log((QuestionCounter / MAX_QUESTIONS) * 100)
const questionIndex = Math.floor(Math.random() * AvailableQuestion.length);
currentQuestion = AvailableQuestion[questionIndex];
question.innerText = currentQuestion.question;
// foreach iterates through the choices
choices.forEach( choice => {
const number = choice.dataset['number'];
// getting number from data-number --- game.html
choice.innerText = currentQuestion['choice' number]
})
AvailableQuestion.splice(questionIndex, 1);
acceptingAnswer = true
};
choices.forEach(choice => {
choice.addEventListener("click", e=> {
if(!acceptingAnswer) return;
acceptingAnswer = false;
const selectedChoice = e.target;
const selectedAnswer = selectedChoice.dataset["number"];
// Different ways of using conditions
// const classToApply = 'incorrect';
// if(selectedAnswer == currentQuestion.answer){
// classToApply = 'correct;'
// }
const classToApply = selectedAnswer == currentQuestion.answer ? 'correct' : 'incorrect';
if (classToApply === 'correct'){
incrementScore(CORRECT_BONUS)
}
else{
decrementScore(INCORRECT)
}
// console.log(classToApply)
selectedChoice.parentElement.classList.add(classToApply)
setTimeout(() => {
selectedChoice.parentElement.classList.remove(classToApply)
getNewQuestion()
}, 250);
// console.log(selectedAnswer == currentQuestion.answer)
})
})
incrementScore = num => {
Score = num;
scoreText.innerText = Score;
}
decrementScore = num => {
Score -= num;
scoreText.innerText = Score;
}
startgame()
/////game.html///
<!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>Game - Play</title>
<link rel="stylesheet" href="app.css" >
<link rel="stylesheet" href="game.css">
</head>
<body>
<div >
<div id="game" >
<div id="hud">
<div id="hud-item">
<p id="progressText" >
Question
</p>
<div id="progressBar">
<div id="progressBarFull"> </div>
</div>
</div>
<div id="hud-item">
<p >
Score
</p>
<h1 id="score">
0
</h1>
</div>
</div>
<h2 id="question">
Answer to this question?
</h2>
<div >
<p >A</p>
<p data-number="1">Choice 1</p>
</div>
<div >
<p >B</p>
<p data-number="2">Choice 2</p>
</div>
<div >
<p >C</p>
<p data-number="3">Choice 3</p>
</div>
<div >
<p >D</p>
<p data-number="4">Choice 4</p>
</div>
</div>
</div>
<script src="game.js"></script>
</body>
</html>
//////game.css////
.choice-container{
display: flex;
margin-bottom: 0.5rem;
width: 100%;
font-size: 1.8rem;
border:0.1rem solid rgb(86, 235, 0.25);
background-color: white;
}
.choice-container:hover{
cursor: pointer;
box-shadow: 0 0.4rem 1.4rem 0 rgb(86, 165, 235, 0.5);
transform: translate(-0.1rem);
transition: transfor 150ms;
}
.choice-prefix{
padding:1.5rem 2.5rem;
background-color: #56a5eb;
color: white;
}
.choice-text{
padding: 1.5rem;
width: 100%;
}
.correct{
background-color: #28a745;
}
.incorrect{
background-color: #dc3545;
}
/* HUD */
#hud {
display: flex;
justify-content: space-evenly;
}
.hud-prefix{
text-align: center;
font-size: 2rem;
}
.hud-main-text{
text-align: center;
}
#progressBar{
width: 20rem;
height: 4rem;
border: 0.3rem solid #56a5eb;
margin-top: 0.9rem;
}
#progressBarFull{
height: 3.4rem;
background-color:#56a5eb;
width: 0%;
}
CodePudding user response:
Irrespective of other issues, the issue is that you are setting an invalid style on progressBarFull.
You have whitespace in your js:
progressBarFull.style.width = `${(QuestionCounter / MAX_QUESTIONS) * 100} %`
This results in setting an invalid style, which won't even show up in the DOM in something like inspect. For a percentage (%) specifier, it needs to be right after the numeric value.
CodePudding user response:
Here is a example that might work for you. This is using jQuery, yet can also be converted to Vanilla JS.
$(function() {
function setProgress(current, total) {
var perc = Math.floor((current / total) * 100);
$("#progressBarFull").css("width", perc "%");
}
$("button").click(function() {
setProgress($(this).val(), 3);
$(this).prop("disabled", true).next().prop("disabled", false);
});
});
#hud {
display: flex;
justify-content: space-evenly;
}
.hud-prefix {
text-align: center;
font-size: 2rem;
}
.hud-main-text {
text-align: center;
}
#progressBar {
width: 20rem;
height: 4rem;
border: 0.3rem solid #56a5eb;
margin-top: 0.9rem;
}
#progressBarFull {
height: 3.4rem;
background-color: #56a5eb;
width: 0%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="hud">
<div id="hud-item">
<p id="progressText" >
Question
</p>
<div id="progressBar">
<div id="progressBarFull"> </div>
</div>
</div>
<div id="hud-item">
<p >
Score
</p>
<h1 id="score">
0
</h1>
</div>
</div>
<button value="1">Answer 1</button>
<button value="2" disabled="true">Answer 2</button>
<button value="3" disabled="true">Answer 3</button>