Reputation: 135
I am trying to make a simple quiz using javascript with timed questions. Each question lasts for 10 seconds before moving on to the next. The countdown timer does well for the first question, after which it starts to speed up or display random numbers for following questions. Here is my code, P.S. I apologize for the inefficient and hectic code, I'm still new to javascript and I will make the code more streamlined once I fix this issue.
var questionList = [
{
q:"What is a dog?",
a:["fish","mammal","plant","prokaryote"],
answer: 1
},
{
q:"What is a cat?",
a:["mammal","fish","plant","amphibian"],
answer: 0
},
{
q:"What is a tree?",
a:["plant","fish","mammal","none"],
answer: 0
},
{
q:"What do cars run on?",
a:["gasoline","water","ethanol","liquid oxygen"],
answer: 0
},
{
q:"What is 4 x 4?",
a:["8","16","4","160"],
answer: 1
},
{
q:"What is the capital of Australia?",
a:["Brisbane","GoldCoast","Perth","Canberra","Melbourne"],
answer: 3
},
{
q:"What is the national flower of Canada?",
a:["sunflower","daisy","trillium","rose","lotus"],
answer: 2
}
];
//--------------------------------------
var picked;
var qcount = 0;
var output = [];
var timer;
var timer2;
var timeLeft = 10;
var correctQ = 0;
var wrongQ = 0;
//var randomQ = Math.floor(Math.random()*7);
var x = questionList[qcount];
var j = x.answer;
// var cAns = x.a[j];
//console.log(cAns);
console.log(j);
//new Q w/ options
function qGen(){
timer = setInterval(time, 1000)
$('#question').text(x.q);
for (var i=0; i < (x.a).length; i++){
var newLi = $('<button>');
newLi.attr('data-id', i);
newLi.addClass("answer").text(x.a[i]);
$('#list').append(newLi);
}
}
qGen();
// correct answer
function clickChoice(){
$('#list').on("click",'button', function(){
picked = parseInt($(this).attr("data-id"));
console.log(picked + " click");
if (picked === j){
console.log(j + " if");
qcount++;
x = questionList[qcount];
j = x.answer;
qGen();
correct();
}else{
qcount++;
incorrect();
x = questionList[qcount];
j = x.answer;
qGen();
}
})
}
clickChoice();
//timer
function time(){
timeLeft--;
$('#time').text(timeLeft);
if(timeLeft===0){
$('#score').text('TIME UP');
timer2 = setInterval(timeUp, 2000);
}
}
//time up
function timeUp(){
clearInterval(timer);
wrongQ++;
qcount++;
x = questionList[qcount];
j = x.answer;
clearInterval(timer2);
nextQ();
}
//correct
function correct(){
clearInterval(timer);
clearInterval(timer2);
$("#list").text("");
correctQ++;
nextQ();
}
//incorrect
function incorrect(){
clearInterval(timer);
clearInterval(timer2);
$("#list").text("");
wrongQ++;
nextQ();
}
//next question gen
function nextQ(){
timeLeft= 10;
$('#score').text("");
$('#ca').text("");
$('#question').text(x.q);
//$("#time").text(timeLeft);
$("#list").text("");
qGen();
}
Upvotes: 2
Views: 165
Reputation: 7821
Below is a modified version of your code, which should solve your issues.
Notes
HTML
and CSS
score
updating, but that should be straight forward given the belowconst questionList = [
{
q: 'What is a dog?',
a: ['fish', 'mammal', 'plant', 'prokaryote'],
answer: 1
},
{
q: 'What is a cat?',
a: ['mammal', 'fish', 'plant', 'amphibian'],
answer: 0
},
{
q: 'What is a tree?',
a: ['plant', 'fish', 'mammal', 'none'],
answer: 0
},
{
q: 'What do cars run on?',
a: ['gasoline', 'water', 'ethanol', 'liquid oxygen'],
answer: 0
},
{
q: 'What is 4 x 4?',
a: ['8', '16', '4', '160'],
answer: 1
},
{
q: 'What is the capital of Australia?',
a: ['Brisbane', 'GoldCoast', 'Perth', 'Canberra', 'Melbourne'],
answer: 3
},
{
q: 'What is the national flower of Canada?',
a: ['sunflower', 'daisy', 'trillium', 'rose', 'lotus'],
answer: 2
}
];
//--------------------------------------
let picked;
let qcount = 0;
const output = [];
let timer;
const startingTime = 10;
let timeLeft;
let correctQ = 0;
let wrongQ = 0;
// var randomQ = Math.floor(Math.random()*7);
// let x = questionList[qcount];
// let j = x.answer;
// var cAns = x.a[j];
// console.log(cAns);
// console.log(j);
// next question gen
function nextQ() {
timeLeft = 10;
document.querySelector('#score').textContent = '';
// document.querySelector('#ca').textContent = '';
document.querySelector('#question').textContent = questionList[qcount].q;
// $("#time").text(timeLeft);
document.querySelector('#list').textContent = '';
qGen();
}
// time up
function timeUp() {
clearInterval(timer);
wrongQ += 1;
qcount += 1;
nextQ();
}
// correct
function correct() {
clearInterval(timer);
correctQ += 1;
nextQ();
}
// incorrect
function incorrect() {
clearInterval(timer);
wrongQ += 1;
nextQ();
}
// timer
function time() {
timeLeft -= 1;
document.querySelector('#time').textContent = timeLeft;
if (timeLeft === 0) {
document.querySelector('#score').textContent = 'TIME UP';
timeUp();
}
}
// Add EventListener to each button
function addEL(el) {
el.addEventListener('click', event => {
picked = parseInt(event.currentTarget.getAttribute('data-id'), 10);
console.log(`${picked} click`);
const correctAnswer = questionList[qcount].answer;
qcount += 1;
if (picked === correctAnswer) {
console.log(`${correctAnswer} if`);
correct();
} else {
incorrect();
}
});
}
// new Q w/ options
function qGen() {
const x = questionList[qcount];
timeLeft = startingTime;
document.querySelector('#time').textContent = startingTime;
document.querySelector('#question').textContent = x.q;
for (let i = 0; i < x.a.length; i += 1) {
const newLi = document.createElement('li');
const answer = document.createElement('button');
answer.setAttribute('data-id', i);
answer.classList.add('answer');
answer.textContent = x.a[i];
addEL(answer);
newLi.appendChild(answer);
document.querySelector('#list').appendChild(newLi);
}
timer = setInterval(time, 1000);
}
document.addEventListener('DOMContentLoaded', () => {
qGen();
});
.answer {
background-color: yellow;
}
<div>
Question:
<span id="question">XXX</span>
</div>
<div>
Time:
<span id="time">XXX</span>
</div>
<div>
Score:
<span id="score">XXX</span>
</div>
<div>
<ul id="list">
</ul>
</div>
Below are the changes I made, including some tips on good practices in JavaScript.
Code Logic
qGen
twice, effectively spinning up two new intervals on each click<li>
elements are permitted inside <ul>
/ <ol>
<li>
s.DOMContentLoaded
event listeneroutput
, correctQ
, wrongQ
: These assigned values are never used in your codeGood Practices
event.currentTarget
instead of this
inside event listenerUpvotes: 1