Your Page Title
🔍

    JS Quiz

    You’re looking to create a JavaScript quiz tutorial! This is a fantastic way to apply core JavaScript concepts like DOM manipulation, events, arrays, objects, and conditional logic. We’ll build a simple multiple-choice quiz from scratch.

    The Core Components of a JavaScript Quiz

    A typical quiz involves:

    1. Questions and Answers: Stored as JavaScript data.
    2. Display Logic: Showing one question at a time.
    3. User Interaction: Handling answer selections.
    4. Scoring Logic: Checking answers and tallying points.
    5. Feedback: Telling the user if their answer was correct/incorrect.
    6. Navigation: Moving to the next question.
    7. Results: Displaying the final score.

    HTML Structure for Our Quiz

    Let’s set up the basic HTML. We’ll need a container for the quiz, elements to display the question, answer choices, a “next” button, and a place for the score.

    HTML

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>JavaScript Quiz</title>
        <style>
            body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f4f7f6; margin: 0; }
            .quiz-container {
                background-color: #ffffff;
                padding: 30px;
                border-radius: 10px;
                box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
                width: 90%;
                max-width: 600px;
                text-align: center;
            }
            h1 { color: #333; margin-bottom: 25px; }
            #question-display {
                font-size: 1.4em;
                margin-bottom: 25px;
                color: #555;
                min-height: 60px; /* To prevent layout shift */
            }
            .answers-container {
                display: flex;
                flex-direction: column;
                gap: 10px;
                margin-bottom: 25px;
            }
            .answer-button {
                background-color: #e0e0e0;
                border: 1px solid #ccc;
                padding: 12px 15px;
                font-size: 1em;
                cursor: pointer;
                border-radius: 8px;
                transition: background-color 0.2s, transform 0.1s;
                text-align: left; /* Align text to the left for better readability */
            }
            .answer-button:hover {
                background-color: #d0d0d0;
                transform: translateY(-2px);
            }
            .answer-button.selected {
                background-color: #c9e6ff;
                border-color: #007bff;
                font-weight: bold;
            }
            .answer-button.correct {
                background-color: #d4edda;
                border-color: #28a745;
                font-weight: bold;
            }
            .answer-button.incorrect {
                background-color: #f8d7da;
                border-color: #dc3545;
                font-weight: bold;
            }
            #feedback {
                margin-top: -10px; /* Adjust spacing */
                margin-bottom: 15px;
                font-weight: bold;
                min-height: 20px; /* Prevent layout shift */
            }
            #next-button {
                background-color: #007bff;
                color: white;
                padding: 12px 25px;
                font-size: 1.1em;
                border: none;
                border-radius: 8px;
                cursor: pointer;
                transition: background-color 0.2s;
            }
            #next-button:hover {
                background-color: #0056b3;
            }
            #next-button:disabled {
                background-color: #cccccc;
                cursor: not-allowed;
            }
            #score-display {
                font-size: 1.8em;
                color: #28a745;
                margin-top: 30px;
            }
        </style>
    </head>
    <body>
        <div class="quiz-container">
            <h1>JavaScript Quiz!</h1>
            <p id="question-display">Question will appear here.</p>
            <div class="answers-container" id="answers">
                </div>
            <p id="feedback"></p>
            <button id="next-button" disabled>Next Question</button>
            <p id="score-display" style="display: none;"></p>
        </div>
    
        <script>
            // JavaScript quiz logic will go here
        </script>
    </body>
    </html>
    

    JavaScript Quiz Logic

    Now, let’s write the JavaScript to power our quiz.

    JavaScript

    document.addEventListener('DOMContentLoaded', function() {
        // 1. Quiz Data
        const quizQuestions = [
            {
                question: "What does JS stand for?",
                answers: [
                    { text: "Just Script", correct: false },
                    { text: "JavaScript", correct: true },
                    { text: "Jazzy Script", correct: false },
                    { text: "Junior Script", correct: false }
                ]
            },
            {
                question: "Which keyword is used to declare a constant variable in JS?",
                answers: [
                    { text: "var", correct: false },
                    { text: "let", correct: false },
                    { text: "const", correct: true },
                    { text: "static", correct: false }
                ]
            },
            {
                question: "What is the correct way to write an array in JavaScript?",
                answers: [
                    { text: "{1, 2, 3}", correct: false },
                    { text: "(1, 2, 3)", correct: false },
                    { text: "[1, 2, 3]", correct: true },
                    { text: "<1, 2, 3>", correct: false }
                ]
            },
            {
                question: "Which method is used to add an element to the end of an array?",
                answers: [
                    { text: "append()", correct: false },
                    { text: "push()", correct: true },
                    { text: "addToEnd()", correct: false },
                    { text: "last()", correct: false }
                ]
            }
        ];
    
        // 2. DOM Element References
        const questionDisplay = document.getElementById('question-display');
        const answersContainer = document.getElementById('answers');
        const feedbackParagraph = document.getElementById('feedback');
        const nextButton = document.getElementById('next-button');
        const scoreDisplay = document.getElementById('score-display');
    
        // 3. Quiz State Variables
        let currentQuestionIndex = 0;
        let score = 0;
        let selectedAnswerButton = null; // To keep track of the selected answer
    
        // 4. Function to Load a Question
        function loadQuestion() {
            // Reset previous state
            resetQuizState();
    
            if (currentQuestionIndex < quizQuestions.length) {
                const questionData = quizQuestions[currentQuestionIndex];
                questionDisplay.textContent = `${currentQuestionIndex + 1}. ${questionData.question}`;
    
                questionData.answers.forEach(answer => {
                    const button = document.createElement('button');
                    button.textContent = answer.text;
                    button.classList.add('answer-button');
                    button.dataset.correct = answer.correct; // Store correct state as a data attribute
                    answersContainer.appendChild(button);
    
                    button.addEventListener('click', selectAnswer);
                });
                nextButton.disabled = true; // Disable next button until an answer is selected
            } else {
                // Quiz finished
                showResults();
            }
        }
    
        // 5. Function to Handle Answer Selection
        function selectAnswer(event) {
            // If an answer was already selected, deselect it visually
            if (selectedAnswerButton) {
                selectedAnswerButton.classList.remove('selected');
            }
    
            const clickedButton = event.target;
            clickedButton.classList.add('selected');
            selectedAnswerButton = clickedButton; // Store reference to the selected button
    
            // Enable the next button as an answer has been selected
            nextButton.disabled = false;
            feedbackParagraph.textContent = ""; // Clear any previous feedback
    
            // Optional: Provide immediate feedback if desired (but for a quiz, usually after 'Next')
            // const isCorrect = JSON.parse(clickedButton.dataset.correct);
            // feedbackParagraph.textContent = isCorrect ? "Correct!" : "Incorrect!";
            // feedbackParagraph.style.color = isCorrect ? "green" : "red";
        }
    
        // 6. Function to Check Answer and Advance
        function checkAnswerAndAdvance() {
            if (!selectedAnswerButton) {
                alert("Please select an answer before proceeding!");
                return;
            }
    
            // Disable all answer buttons to prevent re-selection
            Array.from(answersContainer.children).forEach(button => {
                button.disabled = true;
            });
    
            const isCorrect = JSON.parse(selectedAnswerButton.dataset.correct); // Convert string 'true'/'false' to boolean
    
            // Provide visual feedback (correct/incorrect styling)
            if (isCorrect) {
                selectedAnswerButton.classList.add('correct');
                feedbackParagraph.textContent = "Correct!";
                feedbackParagraph.style.color = "green";
                score++;
            } else {
                selectedAnswerButton.classList.add('incorrect');
                feedbackParagraph.textContent = "Incorrect.";
                feedbackParagraph.style.color = "red";
                // Also show the correct answer
                Array.from(answersContainer.children).forEach(button => {
                    if (JSON.parse(button.dataset.correct)) {
                        button.classList.add('correct'); // Highlight the correct answer
                    }
                });
            }
    
            nextButton.textContent = (currentQuestionIndex === quizQuestions.length - 1) ? "Show Results" : "Next Question";
            nextButton.disabled = false; // Ensure next button is enabled to advance
            
            // Wait a moment before loading the next question or showing results
            setTimeout(() => {
                currentQuestionIndex++;
                loadQuestion();
            }, 1500); // Wait 1.5 seconds before moving to next question/results
        }
    
        // 7. Function to Reset Quiz State for Next Question
        function resetQuizState() {
            answersContainer.innerHTML = ''; // Clear previous answer buttons
            feedbackParagraph.textContent = ''; // Clear feedback
            feedbackParagraph.style.color = ''; // Reset feedback color
            nextButton.textContent = 'Next Question';
            nextButton.disabled = true;
            selectedAnswerButton = null; // Reset selected answer
        }
    
        // 8. Function to Show Final Results
        function showResults() {
            questionDisplay.style.display = 'none';
            answersContainer.style.display = 'none';
            feedbackParagraph.style.display = 'none';
            nextButton.style.display = 'none';
    
            scoreDisplay.textContent = `Quiz Complete! You scored ${score} out of ${quizQuestions.length}!`;
            scoreDisplay.style.display = 'block';
        }
    
        // Event Listener for the Next Button
        nextButton.addEventListener('click', checkAnswerAndAdvance);
    
        // Initial load of the first question
        loadQuestion();
    });
    

    Explanation of the JavaScript Logic:

    1. quizQuestions Array: This array of objects holds all our quiz data. Each object has a question string and an answers array. Each answer object has text and a correct boolean.
    2. DOM References: We get references to the HTML elements we need to manipulate.
    3. State Variables:
      • currentQuestionIndex: Tracks which question we’re currently on.
      • score: Keeps track of the user’s correct answers.
      • selectedAnswerButton: A variable to store the button element the user clicked, so we can access its properties later.
    4. loadQuestion():
      • Clears previous answers and feedback.
      • Checks if there are more questions. If not, it calls showResults().
      • Updates questionDisplay with the current question.
      • Iterates through questionData.answers using forEach().
      • For each answer, it document.createElement('button'), sets its textContent, adds the answer-button CSS class, and importantly, sets a data-correct attribute (a custom attribute to store the correct state) which makes it easy to retrieve the correctness.
      • Appends the created button to the answersContainer.
      • Attaches a click event listener to each answer button, calling selectAnswer.
      • Disables the nextButton until an answer is selected.
    5. selectAnswer(event):
      • This function runs when an answer button is clicked. event.target refers to the specific button clicked.
      • It manages the visual selected class, ensuring only one button looks selected at a time.
      • Enables the nextButton because an answer has now been chosen.
    6. checkAnswerAndAdvance():
      • First, it checks if an answer was actually selected.
      • It disables all answer buttons to prevent further clicks for the current question.
      • It retrieves the correct state from the selectedAnswerButton.dataset.correct (remember to JSON.parse it as data attributes are always strings).
      • Updates the score if correct.
      • Applies correct or incorrect CSS classes for visual feedback and updates the feedbackParagraph.
      • If the answer was incorrect, it also highlights the correct answer’s button.
      • Changes the text of the nextButton to “Show Results” if it’s the last question.
      • Uses setTimeout() to pause briefly (1.5 seconds) before incrementing currentQuestionIndex and calling loadQuestion() again, giving the user time to see the feedback.
    7. resetQuizState(): Clears the previous answers, feedback, and resets the “next” button’s state, preparing the UI for the next question.
    8. showResults(): Hides the quiz elements and displays the final score.
    9. Event Listener for nextButton: The nextButton‘s click event directly calls checkAnswerAndAdvance().
    10. Initial Call: loadQuestion() is called once DOMContentLoaded to start the quiz.

    This setup provides a robust, interactive, and user-friendly JavaScript quiz experience. You can easily extend it by adding more questions, different types of feedback, timers, or more complex scoring mechanisms.

    Leave a Reply

    Your email address will not be published. Required fields are marked *