如何为测验题目按类别(如数学/英语/科学)高效实现分类计分
Great question! Here's a clean, efficient way to add category labels to your quiz questions and calculate scores per category without redundant code:
Step 1: Add Category Labels to Your Questions
First, extend each question object with a category property to define which subject it belongs to. I also fixed the correct answer for the Science question (H2O should be the right choice):
const questions = [{ question: "What does 2+2 equal?", category: "Math", // Added category answers: [{ text: "4", value: 1 }, { text: "2", value: 0 }, { text: "8", value: 0 }, { text: "16", value: 0 } ] }, { question: "What does obliterate most nearly mean?", category: "English", // Added category answers: [{ text: "translate", value: 0 }, { text: "scatter", value: 0 }, { text: "wipe out", value: 1 }, { text: "blame", value: 0 } ] }, { question: "What is the chemical formula for water?", category: "Science", // Added category answers: [{ text: "H2O", value: 1 // Fixed correct answer }, { text: "K", value: 0 }, { text: "Na", value: 0 }, { text: "H", value: 0 } ] } ];
Step 2: Track Scores by Category
Instead of a single totalScore variable, use an object to store scores for each category. We'll initialize it dynamically based on the categories in your questions:
// Initialize the current question index let currentQuestionIndex = 0; // Track the category of the currently active question let currentCategory = ""; // Create a score object with all unique categories starting at 0 const uniqueCategories = [...new Set(questions.map(q => q.category))]; let categoryScores = Object.fromEntries(uniqueCategories.map(cat => [cat, 0]));
Step 3: Update Score Logic to Use Categories
Modify the showNextQuestion function to set the current category when loading a question, then update updateScore to add points to the correct category:
function showNextQuestion() { // Hide the form document.getElementById("form").style.display = "none"; // Show the question and answers document.getElementById("question").style.display = "block"; document.getElementById("answers").style.display = "block"; document.getElementById("next-button").style.display = "block"; if (currentQuestionIndex < questions.length) { const currentQuestion = questions[currentQuestionIndex]; currentCategory = currentQuestion.category; // Set active category // Update the question text document.getElementById("question").innerHTML = currentQuestion.question; // Clear answers document.getElementById("answers").innerHTML = ''; // Show the answers for the current question for (const answer of currentQuestion.answers) { document.getElementById("answers").innerHTML += ` <input type="radio" name="answer" value="${answer.value}" onchange="updateScore(this)"> ${answer.text}<br> `; } currentQuestionIndex++; } if (currentQuestionIndex === questions.length) { // Hide Next, show Submit document.getElementById("next-button").style.display = "none"; document.getElementById("submit-button").style.display = "block"; } } function updateScore(selectedAnswer) { if (!selectedAnswer.checked) { return; } // Add points to the current category's score categoryScores[currentCategory] += parseInt(selectedAnswer.value); // Uncheck other radio buttons (unchanged) const radioButtons = document.getElementsByName("answer"); for (const radioButton of radioButtons) { if (radioButton !== selectedAnswer) { radioButton.checked = false; } } }
Step 4: Display Per-Category Scores
Update showTotalScore to render each category's score (plus a total if you want):
function showTotalScore() { // Hide question/answer elements document.getElementById("question").style.display = "none"; document.getElementById("answers").style.display = "none"; document.getElementById("submit-button").style.display = "none"; // Calculate total score (optional) const totalScore = Object.values(categoryScores).reduce((sum, score) => sum + score, 0); // Build HTML for category scores let scoreHtml = `<h3>Your Quiz Results:</h3>`; for (const [category, score] of Object.entries(categoryScores)) { scoreHtml += `<p><strong>${category}:</strong> ${score}</p>`; } scoreHtml += `<hr><p><strong>Total Score:</strong> ${totalScore}</p>`; // Display the results const totalScoreElement = document.getElementById("total-score"); totalScoreElement.style.display = "block"; totalScoreElement.innerHTML = scoreHtml; }
Why This Works
- No Redundancy: The same logic works for any number of categories—just add more questions with new categories, and the code will automatically track their scores.
- Dynamic Initialization: We use
Setto get unique categories from your questions, so you don't have to manually update the score object when adding new subjects. - Clean Tracking: The
currentCategoryvariable ensures we always add points to the right subject when an answer is selected.
Your HTML doesn't need any changes—existing elements will handle the new score display just fine.
内容的提问来源于stack exchange,提问作者Rob

