项目说明:一个测验应用程序,其中包含特定数量的问题和答案,其中数据是从数组中检索的。
为了跟踪正确答案,我创建了一个名为 (rightAnswers) 的变量,从零开始,当用户回答正确问题时,该变量的值增加 1。 在问题结束时,应该出现一个用户结果,说明用户回答了多少个正确的问题。
我有一个名为 checkAnswer 的函数,它将用户选择的答案与正确答案进行比较,如果是,则将 rightAttempts 值增加一个
问题: 回答问题的数量总是有问题(有时答对所有问题,消息说我正确回答了9个问题中的14个)
更好地理解问题的方法: 选择每个正确答案后,我在控制台记录 rightAnswers 变量以查看它的值。
问题:
0 并在 .
之后立即为 1
2 然后 3 然后 4 每行 .
我不明白为什么这些增量会紧接着彼此发生,而变量只需要增加一个。
值得注意的是,当我以错误的方式回答了前两个问题,然后尝试了其余的问题时,这种奇怪的事情也发生在其余测验的随机问题上。
我真的不明白为什么会这样。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quiz app</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="quiz-container">
<div class="quiz-info">
<div class="category">Category: HTML</div>
<div class="questions-count">Questions count: <span></span></div>
</div>
<div class="quiz-area">
<div class="question"></div>
<div class="answers-area"></div>
</div>
<button class="submit">Submit Answer</button>
<div class="controls">
<div class="bullets"></div>
<div class="countdown"></div>
</div>
<div class="results"></div>
</div>
<script src="app.js"></script>
</body>
</html>
* {
box-sizing: border-box;
}
body {
font-family: Tahoma, sans-serif;
}
.quiz-container {
width: 800px;
padding: 15px;
margin: auto;
margin-top: 100px;
border-radius: 5px;
background-color: #ddd;
}
.quiz-info {
background-color: white;
padding: 8px;
display: flex;
justify-content: space-between;
align-items: center;
height: 45px;
margin-bottom: 10px;
}
.quiz-area {
background-color: white;
padding: 10px;
}
.quiz-area h2 {
margin: 0;
margin-bottom: 10px;
}
.answers-area {
background-color: #ddd;
padding: 5px;
}
.answers-area .answer {
margin: 10px;
padding-bottom: 3px;
}
.answers-area .answer label {
position: relative;
top: -1px;
cursor: pointer;
}
.answers-area .answer input[type='radio']:checked + label {
color: #0075ff;
}
.answers-area .answer:not(:last-child) {
border-bottom: 1px solid #8b8a8a;
/* This is just a random color and not from the material
design colors . */
}
.submit {
width: 100%;
color: white;
background-color: #0075ff;
border-radius: 15px;
border: none;
text-align: center;
margin-top: 10px;
padding: 10px;
font-size: 24px;
cursor: pointer;
}
.submit:focus {
outline: none;
}
.controls {
background-color: white;
display: flex;
justify-content: space-between;
align-items: center;
padding: 5px;
margin-top: 10px;
}
.controls .bullets span {
display: inline-block;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #ddd;
margin-left: 5px;
}
.controls .bullets span.active {
background-color: #0075ff;
}
.results {
background-color: white;
padding: 10px;
margin-top: 10px;
display: none;
}
.results span.perfect {
color: #0075ff;
}
.results span.very-good {
color: #009688;
}
.results span.good {
color: #dc0a0a;
}
let questionsCountSpan = document.querySelector('.questions-count span');
let bulletsContainer = document.querySelector('.bullets');
let questionContainer = document.querySelector('.question');
let answersArea = document.querySelector('.answers-area');
let submitBtn = document.querySelector('.submit');
// Set utilities
let currentIndex = 0;
let rightAnswers = 0;
let countdownInterval;
let questionsArray = [
{
title: "What is the use of <br> Element",
answer_1: "Make the text bold",
answer_2: "Make the text italic",
answer_3: "Add Breakline",
answer_4: "Create Horizontal Line",
right_answer: "Add Breakline"
},
{
title: "Does <img> Element have href attribute in it's syntax",
answer_1: "Yes",
answer_2: "No, It's for Anchor Tag <a>",
answer_3: "All Elements have this attribute",
answer_4: "Answers 1 and 3 are right",
right_answer: "No, It's for Anchor Tag <a>"
},
{
title: "How can we make the text of an element bold",
answer_1: "Putting It Inside <b> Tag",
answer_2: "Putting It Inside <strong> Tag",
answer_3: "Customizing it with font-weight property in CSS",
answer_4: "All answers are right",
right_answer: "All answers are right"
},
{
title: "What is the right hierarchy for creating part of a page",
answer_1: "<h2> Then <p> Then <h1> Then <p> Then <h3> Then <p> Then <img>",
answer_2: "<h1> Then <p> Then <h3> Then <p> Then <h2> Then <p> Then <img>",
answer_3: "<h2> Then <p> Then <h3> Then <p> Then <h1> Then <p> Then <img>",
answer_4: "All solutions are wrong",
right_answer: "All solutions are wrong"
},
{
title: "How can we include an external page inside our HTML page",
answer_1: "By using include in HTML",
answer_2: "By using load In HTML",
answer_3: "By using iFrame Tag",
answer_4: "All solutions are wrong",
right_answer: "By using iFrame Tag"
},
{
title: "What is the tag that doesn't exist in HTML",
answer_1: "<object>",
answer_2: "<basefont>",
answer_3: "<abbr>",
answer_4: "All Tags exist in HTML",
right_answer: "All Tags exist in HTML"
},
{
title: "How do we specify document type of an HTML5 Page",
answer_1: "<DOCTYPE html>",
answer_2: "<DOCTYPE html5>",
answer_3: "<!DOCTYPE html5>",
answer_4: "<!DOCTYPE html>",
right_answer: "<!DOCTYPE html>"
},
{
title: "What is the element that doesn't exist in HTML5 Semantics",
answer_1: "<article>",
answer_2: "<section>",
answer_3: "<blockquote>",
answer_4: "<aside>",
right_answer: "<blockquote>"
},
{
title: "In HTML, which way can we use to add attributes",
answer_1: "<div class='class-name'>",
answer_2: "<div class=class-name>",
answer_3: "<div class=\"class-name\">",
answer_4: "All are right",
right_answer: "All are right"
}
];
function getQuestions() {
let qCount = questionsArray.length;
createBullets(qCount);
addQuestionData(questionsArray[currentIndex], qCount);
submitBtn.onclick = function() {
let rightAnswer = questionsArray[currentIndex]["right_answer"];
checkAnswer(rightAnswer, qCount);
currentIndex++;
questionContainer.innerHTML = '';
answersArea.innerHTML = '';
addQuestionData(questionsArray[currentIndex], qCount);
handleBullets();
showResults(qCount);
}
}
getQuestions();
function createBullets(num) {
questionsCountSpan.innerHTML = num;
for (let i = 0; i < num; i++) {
let bullet = document.createElement('span');
if (i === 0) {
bullet.className = 'active';
}
bulletsContainer.append(bullet);
}
}
function addQuestionData(object, qCount) {
if (currentIndex < qCount) {
// Add the question
let questionHeading = document.createElement('h2');
questionHeading.append(object['title'] + ' ?');
questionContainer.append(questionHeading);
// Add the answers
for (let i = 1; i <= 4; i++) {
let answerDiv = document.createElement('div');
answerDiv.className = 'answer';
let radioInput = document.createElement('input');
radioInput.type = 'radio';
radioInput.id = `answer_${i}`;
radioInput.name = 'question';
radioInput.dataset.answer = object[`answer_${i}`];
if (i === 1) {
radioInput.checked = true;
}
answerDiv.append(radioInput);
let label = document.createElement('label');
label.htmlFor = `answer_${i}`;
label.textContent = object[`answer_${i}`];
answerDiv.append(label);
answersArea.append(answerDiv);
}
}
}
function checkAnswer(correctAnswer, qCount) {
let answers = document.getElementsByName('question');
let chosenAnswer;
for (let i = 0; i < answers.length; i++) {
if (answers[i].checked) {
chosenAnswer = answers[i].dataset.answer;
}
if (correctAnswer === chosenAnswer) {
console.log(rightAnswers);
rightAnswers++;
}
}
}
function handleBullets() {
let bullets = document.querySelectorAll('.bullets span');
bullets.forEach((bullet, index) => {
if (currentIndex === index) {
bullet.className = 'active';
}
})
}
function showResults(count) {
let quizArea = document.querySelector('.quiz-area');
let resultsContainer = document.querySelector('.results');
let controls = document.querySelector('.controls');
if (currentIndex === count) {
quizArea.remove();
bulletsContainer.remove();
submitBtn.remove();
controls.remove();
if (rightAnswers === count) {
resultsContainer.innerHTML = `<span class="perfect">Perfect !</span> You \
answered correctly ${rightAnswers} questions \
out of ${count}.`;
} else if (rightAnswers > (count / 2) && rightAnswers < count) {
resultsContainer.innerHTML = `<span class="very-good">Very Good !</span> You \
answered correctly ${rightAnswers} questions \
out of ${count}.`;
} else if (rightAnswers === 0) {
resultsContainer.innerHTML = `<span class="good">Try Again .</span> \
You didn't answer any correct answer. `
} else {
resultsContainer.innerHTML = `<span class="good">Good. </span> You \
answered correctly ${rightAnswers} questions \
out of ${count}.`;
}
resultsContainer.style.display = "block";
}
}
问题出在
checkAnswer
函数中。
假设正确答案是第一个答案,并且用户也选择了那个答案,那么在循环的第一次迭代中
chosenAnswer
将被设置在第一个if
块中。
然后在循环的each迭代中(4次),
rightAnswers
计数器将递增,因为每次第二个if
块都有一个条件为真。
其他正确答案也会出现类似的问题,只是增量的数量会少于四个。
纠正这个问题的一种方法是,一旦增量完成就exit循环:
function checkAnswer(correctAnswer, qCount) {
let answers = document.getElementsByName('question');
let chosenAnswer;
for (let i = 0; i < answers.length; i++) {
if (answers[i].checked) {
chosenAnswer = answers[i].dataset.answer;
}
if (correctAnswer === chosenAnswer) {
console.log(rightAnswers);
rightAnswers++;
break; // <---
}
}
}
通过使用 CSS 立即选择 checked answer 元素,您可以在没有循环的情况下执行此操作:
function checkAnswer(correctAnswer) {
const chosenAnswer = document.querySelector('[name=question]:checked')?.dataset?.answer;
rightAnswers += correctAnswer === chosenAnswer;
}