为什么变量值连续更新多次而不是每次单击按钮一次?

问题描述 投票:0回答:1

项目说明:一个测验应用程序,其中包含特定数量的问题和答案,其中数据是从数组中检索的。

为了跟踪正确答案,我创建了一个名为 (rightAnswers) 的变量,从零开始,当用户回答正确问题时,该变量的值增加 1。 在问题结束时,应该出现一个用户结果,说明用户回答了多少个正确的问题。

我有一个名为 checkAnswer 的函数,它将用户选择的答案与正确答案进行比较,如果是,则将 rightAttempts 值增加一个

问题: 回答问题的数量总是有问题(有时答对所有问题,消息说我正确回答了9个问题中的14个)

更好地理解问题的方法: 选择每个正确答案后,我在控制台记录 rightAnswers 变量以查看它的值。

问题:

  • 正确回答第一个问题后,console.log() 打印:

0 并在 .

之后立即为 1
  • 在正确回答第二个问题时,console.log() 打印:

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";
    }
}
javascript html function loops variables
1个回答
0
投票

问题出在

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.