Want to create a simple quiz web app without all of those “crazy database stuff”? Here’s a simple one that Master Coffee has made, no third-party libraries too. Let’s go!
CODE DOWNLOAD
I have released this under the MIT license, feel free to use it in your own project – Personal or commercial. Some form of credits will be nice though. 🙂
VIDEO TUTORIAL
SIMPLE QUIZ DEMO
PART 1) THE HTML
<div id="qwrap">
<div id="qcurrent"></div>
<div id="qquestion"></div>
<div id="qanswer"></div>
</div>
<div id="qwrap">
The “entire quiz wrapper”.<div id="qcurrent">
The current question number.<div id="qquestion">
The current question.<div id="qanswer">
The answer options.
PART 2) THE JAVASCRIPT
2A) QUESTIONS & ANSWERS
// (PART A) QUESTIONS & ANSWERS - THE FIRST ANSWER IS THE CORRECT ONE
const qa = [
{
q : "What is the smallest planet in the solar system?",
a : ["Mercury", "Earth", "Uranus", "Mars"]
},
{
q : "How many bones do sharks have?",
a : ["0", "356", "235", "108"]
},
{
q : "Where do fortune cookies originate from?",
a : ["Japan", "China", "Korea", "Vietnam"]
},
{
q : "Which country invented ice cream?",
a : ["China", "France", "Italy", "Canada"]
},
{
q : "Where do Frech Fries come from?",
a : ["Belgium", "France", "Germany", "USA"]
}
];
- Well, we don’t have a database to work with. So we use
const qa
to keep all the questions and answers. - Every question has 2 parts –
q
The question itself.a
The answer options, place the correct answer in the first one.
P.S. You can add however many answer options as you like. I just kept it at 4 for simplicity.
2B) QUIZ INIT
var quiz = {
// (PART B) PROPERTIES
hNow : null, // html current question number
hQns : null, // html questions
hAns : null, // html answers
qorder : [], // questions order
aorder : [], // answers order
qnow : 0, // current question
score : 0, // correctly answered
// (PART C) SHUFFLE ARRAY
// CREDIT : https://www.freecodecamp.org/news/how-to-shuffle-an-array-of-items-using-javascript-or-typescript/
shuffle : a => {
for (let i=a.length-1; i>0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
},
// (PART D) INIT QUIZ
init : () => {
// (D1) GET HTML ELEMENTS
quiz.hNow = document.getElementById("qcurrent");
quiz.hQns = document.getElementById("qquestion");
quiz.hAns = document.getElementById("qanswer");
// (D2) SHUFFLE QUESTIONS ORDER
quiz.qorder = [];
for (let i=0; i<qa.length; i++) { quiz.qorder.push(i); }
quiz.shuffle(quiz.qorder);
// (D3) SHOW QUESTION
quiz.qnow = -1;
quiz.next();
},
// ...
};
window.addEventListener("load", quiz.init);
This part may be intimidating to some beginners, but here’s a quick trace:
- (D) On window load, we run
quiz.init()
. - (D1) Get the HTML elements.
hNow
The current question number.hQns
The current question.hAns
The answer options.
- (D2 & C) We shuffle the questions and display them in random order.
qorder
Contains the order of the randomly shuffled questions.
- (D3) Show the first question.
qnow
A flag to track the current question number.
2C) NEXT QUESTION
// (PART E) NEXT QUESTION
next : () => {
// (E1) NEXT QUESTION - SHOW SCORE IF END
quiz.qnow++;
if (quiz.qnow == qa.length) {
quiz.hNow.innerHTML = "The End";
quiz.hQns.innerHTML = `You have answered ${quiz.score} of ${qa.length} correctly.`;
quiz.hAns.innerHTML = "";
// quiz.hAns.innerHTML = "<div onclick='quiz.init()'>Restart</div>";
return;
}
// (E2) GET CURRENT QUESTION
let qn = qa[quiz.qorder[quiz.qnow]];
// (E3) SHUFFLE ANSWERS
quiz.aorder = [];
for (let i=0; i<qn.a.length; i++) { quiz.aorder.push(i); }
quiz.shuffle(quiz.aorder);
// (E4) SHOW QUESTION & ANSWER OPTIONS
quiz.hNow.innerHTML = `Question ${quiz.qnow+1} of ${qa.length}`;
quiz.hQns.innerHTML = qn.q;
quiz.hAns.innerHTML = "";
quiz.aorder.forEach(i => {
let opt = document.createElement("div");
opt.className = "option";
opt.innerHTML = qn.a[i];
opt.order = i;
opt.onclick = () => quiz.pick(i);
quiz.hAns.appendChild(opt);
});
},
- (E1) Simple increment the
qnow
flag to “move” to the next question. Ifqnow == qa.length
, it’s the end of the quiz. - (E2) Get the current question, as according to the randomly shuffled
qorder
. - (E3) Same as the questions, we shuffle the order of the answers.
aorder
Contains the order of the answers to the current question.
- (E4) Pretty self-explanatory. Update the HTML, show the question and answer options.
2D) PICK AN ANSWER OPTION
// (PART F) ON PICKING AN ANSWER OPTION
pick : i => {
// (F1) CORRECTLY ANSWERED
if (i==0) { quiz.score++; }
// (F2) UPDATE ANSWER HTML
document.querySelectorAll("#qanswer div.option").forEach(opt => {
opt.onclick = "";
if (opt.order==0) { opt.classList.add("correct"); }
else if (opt.order==i) { opt.classList.add("wrong"); }
});
// (F3) WAIT FOR 1 SECOND BEFORE NEXT QUESTION
setTimeout(quiz.next, 1000);
}
- (F1) If the user picks the correct answer, we add one point.
score
Total number of correct answers.
- (F2) Highlight the answer options – Show the option that the user picked and the correct answer.
- (F3) Wait for 1 second before moving to the next question.
PART 3) THE CSS
/* (PART A) WHOLE PAGE */
* {
font-family: Arial, Helvetica, sans-serif;
box-sizing: border-box;
}
html, body { color: #fff; background: #2a2d38; }
/* (PART B) QUIZ WRAPPER */
#qwrap {
min-width: 400px; max-width: 600px;
padding: 20px; margin: 0 auto;
}
/* (PART C) CURRENT QUESTION NUMBER */
#qcurrent {
font-size: 16px; color: #959db8;
margin-bottom: 10px;
}
/* (PART D) QUESTION */
#qquestion { font-size: 26px; }
/* (PART E) ANSWER */
#qanswer div.option {
font-size: 18px;
padding: 20px; margin-top: 10px;
border-radius: 5px;
background: #3e4458; cursor: pointer;
}
#qanswer div.wrong { background: #6d221e; }
#qanswer div.correct { background: #1c8d24; }
Well, just a bunch of cosmetics. Feel free to “skin” the quiz however you wish.
THE END – GOOD FOR FUN ONLY
That’s all for this quick tutorial and sharing. Just a quick advice before we end, this simple quiz is good for fun only, don’t use it for examinations and grading. Javascript is client-side, any student can view the source code and get all the correct answers immediately… However, whoever makes the effort to study the code should also be given some credits. 😆