Javascript Checkout
quiz.js
//Variable Declaration
const question = document.querySelector('#question'); //This variable represents the HTML element with the id "question".
const cardContainer = document.querySelector('.card-container'); //class "card-container"
const dropText = document.querySelector('.drop-text'); //class "drop-text"
const progressText = document.querySelector('#progressText'); //id "progressText"
const scoreText = document.querySelector('#score'); //id "score"
const progressBarFull = document.querySelector('#progressBarFull'); //id "progressBarFull"
const declaration - creates block-scoped constants, much like variables declared using the let keyword. Document method querySelector() - returns the first Element within the document that matches the specified selector, or group of selectors.
//Variable Initialization
let currentQuestion = {}; //this variable stores the currently displayed question object
let acceptingAnswers = true; //this variable determines whether the user's answers are accepted or not
let score = 0; //score variable holds current score
let questionCounter = 0; //this variable keeps track of the number of questions answered
let availableQuestions = []; //this variable stores the array of available questions
let selectedChoice = null; //this variable holds the selected choice by the user
//Array of Questions
let questions = [ //declared and initialized the array "questions" with properties like "question" "choice1" to "choice4" and "answer"
{
question: 'Which of the following expressions evaluate to 3.5? \n I. (double) 2 / 4 + 3 \n II. (double) (2 / 4) + 3 \n III.(double) (2 / 4 + 3) ',
choice1: 'I only',
choice2: 'II and III only',
choice3: 'I and II only',
choice4: 'I, II, and III',
answer: 1,
},
{
question: 'Assume that a, b, and c are boolean variables that have been properly declared and initialized. Which of the following boolean expressions is equivalent to !(a && b) || c ?',
choice1: 'a || b || c',
choice2: '!a && !b || c',
choice3: '!a && !b && c',
choice4: '!a || !b || c',
answer: 4,
},
...
];
//Constants
const SCORE_POINTS = 100; // points awarded for each correct answer
const MAX_QUESTIONS = 9; // maximum number of questions in the game
// Function to start the game
startGame = () => { //initializes the game by resetting the question counter, score, and available questions
questionCounter = 0;
score = 0;
availableQuestions = [...questions]; //spread operator to get all the question values in the array
getNewQuestion(); //calls getNewQuestion function to display a new questions
};
startGame = () => { ... };
Arrow functions allow us to write shorter function syntax (w3schools)
The spread (...) syntax allows an iterable, such as an array or string, to be expanded in places.
// Function to retrieve and display a new question
getNewQuestion = () => {
if (availableQuestions.length === 0 || questionCounter >= MAX_QUESTIONS) {
localStorage.setItem('mostRecentScore', score); //save to local storage (not working)
return (window.location.href = 'https://tianbinliu.github.io/CSA-FinalProject/'); //redirect to the menu page
}
questionCounter++; //increment question counter
//update progress text and progress var
progressText.innerText = `Question ${questionCounter} of ${MAX_QUESTIONS}`; //question 1 of 4, 2 of 4, etc. incrementing by 1 each time
progressBarFull.style.width = `${(questionCounter / MAX_QUESTIONS) * 100}%`; //calculate what question we are on and correspond w/ the percentage
//select a random question form the available questions
const questionsIndex = Math.floor(Math.random() * availableQuestions.length); //calculate value of the question index
currentQuestion = availableQuestions[questionsIndex]; //keep track of what questions we are on
question.innerText = currentQuestion.question; //know what the question asked
cardContainer.innerHTML = ''; // Clear the card container, remove previous answer choices
for (let i = 1; i <= 4; i++) { //loop 4 times creating answer choice elements for each iteration
const choiceCard = document.createElement('div'); //create new div and assign it to the choiceCard variable
choiceCard.classList.add('choice-card'); //adds css class choice-card to the choiceCard element
choiceCard.draggable = true; //allow card to be dragged and dropped
choiceCard.dataset.number = i;
choiceCard.innerText = currentQuestion['choice' + i]; //set text to corresponding choice text from currentQuestion object
cardContainer.appendChild(choiceCard); //make answer choice visible within the container
}
availableQuestions.splice(questionsIndex, 1); //splice(start, deleteCount) - remove elements from an array
acceptingAnswers = true;
cardContainer.addEventListener('dragstart', (e) => {
selectedChoice = e.target.dataset.number; //assign data-number attribute from the dragged element to the selectedChoice variable
});
};
const dropArea = document.getElementById('drop-area'); //represent drop area
// Drag and drop event listeners
dropArea.addEventListener('dragover', (e) => { //triggered when card is dragged over the drop area, allowing element to be dropped
e.preventDefault();
});
dropArea.addEventListener('drop', (e) => { //triggered when card is dropped on the drop area
e.preventDefault();
if (!acceptingAnswers) return; //if accpetingAnswers = false, end game
// Get the selected choice from the stored variable
const selectedAnswer = selectedChoice;
let classToApply = selectedAnswer == currentQuestion.answer ? 'correct' : 'incorrect'; //compare selectedAnswer with the correct answer, if match, classToApply = "correct"
console.log('classToApply:', classToApply); //console (for checking)
if (classToApply === 'correct') { //correct answer, called incrementScore function
incrementScore(SCORE_POINTS);
}
dropArea.classList.add(classToApply); //apply styling to indicate whether the answer is correct or not
setTimeout(() => {
dropArea.classList.remove(classToApply);
getNewQuestion();
}, 1000); //delay 1 second, allow user to see visual feedback before moving on to the next question
});
e.preventDefault();
By default, dropping an element onto another element reloads the page or opens the dropped file.
// Function to increment the score
incrementScore = (num) => {
score += num; //adding num to score
scoreText.innerText = score; //innerText - display score
}
startGame(); //initialize the game and display the first questions