面向对象的测验应用

时间:2018-04-25 09:07:15

标签: javascript jquery object

我正在尝试使用javascript构建一个简单的测验应用程序,它很顺利,但是当涉及到验证时会发生奇怪的事情,它会验证我的代码两次!一次使用前一个问题的正确答案,另一次使用当前问题的正确答案! 任何人都可以检查我的代码吗?找出bug的位置?非常感谢

(function () {
// Question Function Constructor
const Question = function (question, answers, correct) {
    this.question = question;
    this.answers = answers;
    this.correct = correct;
}

// Questions Prototypes

Question.prototype.displayQuestion = function () {
    // getting html elements
    const qHolder = $('#question').get(0);
    const list = $('#listOfAnswers').get(0);
    // show questions
    $(qHolder).empty();
    $(qHolder).append(this.question);
    // show answers
    this.answers.forEach(answer => {
        let li = ` <li>
                        <label for="${answer}">
                            <input class="option" type="radio" name="answer" value="${answer}" id="${answer}"> ${answer}
                        </label>
                    </li>`;
        $(list).append(li);
    });
}

Question.prototype.validate = function (ans, callback) {
    let score;
    if (ans === this.correct) {
        console.log('**** TRUE ****');
        score = callback(true);
        console.log(`YOURE ANSWERE === ${ans}`);

    } else {
        console.log('---- FALSE ----');
        score = callback(false);
        console.log(`YOURE ANSWERE === ${ans}`);
        console.log(`CORRECT ANSWER IS =====> ${this.correct}`);

    }
    this.displayScore(score);
}

Question.prototype.displayScore = function (score) {
    console.log(`your current score is : ${score}`);
    console.log(`=======================================================`);
}


// instance of Questions

const q1 = new Question('what\'s max\'s name?', [
    'lax',
    'max',
    'wax',
    'pax',
], 1);

const q2 = new Question('2+2?', [
    '4',
    '12',
    '99',
    'none',
], 0);

const q3 = new Question('... jobs?!', [
    'andrew',
    'what?!',
    'why?!',
    'steve',
], 3);

const q4 = new Question('which one is not a programming language?', [
    'javascript',
    'python',
    'apple',
    'c#',
], 2);


// Array of Questions
const Questions = [q1, q2, q3, q4];
// console.log(Questions);

function score() {
    let sc = 0;
    return function (correct) {
        if (correct) {
            sc++;
        }
        return sc;
    }
}

let keepScore = score();

function nextQuestion() {
    // getting the list and emptying the it for new list items
    const list = $('#listOfAnswers');
    $(list).empty();
    // alerting in the console that its a new question
    console.log('A NEW QUESTION');
    //generate a random number
    let n = Math.floor(Math.random() * Questions.length);
    console.log(`random number generated --> ${n}`);
    // display the question
    Questions[n].displayQuestion();
    console.log(`answer to the question ==>${Questions[n].correct}`);

    // validating the answer by click on the submit button
    const submitBtn = $('#submitBtn');
    submitBtn.on('click', function (e) {
        e.preventDefault();
        let options = $('.option');
        for (i = 0; i < options.length; i++) {
            const option = options[i];
            if ($(option).is(':checked')) {
                // console.log(option);
                userAnswerIndex = i;
                // validation
                Questions[n].validate(userAnswerIndex, keepScore);
            }
        }

    })
}

// displaying next question by clicking next
const nextQbtn = document.querySelector('#next');
nextQbtn.addEventListener('click', nextQuestion);

nextQuestion();
})();

这是我的HTML标记,再次感谢---&gt;

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/style.css">
<title>Quiz App</title>
</head>

<body dir="rtl">

<header>
    <h3>welcome to the quiz app</h3>
</header>
<div class="container">
    <div id="card">
        <header>
            <p id="question">
                <!-- Question displays here -->
            </p>
        </header>
        <form id="answers">
            <ol id="listOfAnswers">
                <!-- answers will generate here -->
            </ol>
        </form>
        <button type="submit" id="submitBtn">submit</button>
        <button id="next">next!</button>
    </div>
</div>

<script src="http://code.jquery.com/jquery-3.3.1.min.js" 
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
    crossorigin="anonymous"></script>
<script src="/quiz.js"></script>
</body>

</html>

2 个答案:

答案 0 :(得分:1)

我无法运行代码以确保,因为我没有相关的标记但是从阅读中看起来似乎问题可以在这段代码中

submitBtn.on('click', function (e) {
        e.preventDefault();
        let options = $('.option');
        for (i = 0; i < options.length; i++) {
            const option = options[i];
            if ($(option).is(':checked')) {
                // console.log(option);
                userAnswerIndex = i;
                // validation
                Questions[n].validate(userAnswerIndex, keepScore);
            }
        }

    })

让我们再次进入let options = $('.option');的第三行,因为我没有标记我可能错了,但这看起来有点可疑。您正在选择具有类option的所有元素,然后迭代它们。在每次迭代中,检查是否选中了选项,是否验证了它。

现在,只有$('.option')只包含一个选定元素时,才能确认验证只运行一次。但是,如果您有多个具有类option的选择或输入元素,并且用户已选择其中多个元素,则可能会获得多个选定元素。在这种情况下,您可能会看到多次验证问题

答案 1 :(得分:0)

您的问题是每次用户按下下一个按钮时,新的点击事件处理程序都会添加到提交按钮。

你会认为,因为它是一个不会发生的功能,但你实际上是一次又一次地这样做。如果用户在提交之前单击下一个按钮三次,则会触发验证功能三次,等等......

您可以通过每次添加活动时删除所有其他点击事件处理程序来处理此问题。 (最简单的一个) 您可以使用jquery off这样做

submitBtn.off().on('click', function (e) {

在添加新活动之前,您只需取消绑定所有点击事件处理程序。 (这样,您的提交按钮上总会有一个单击事件处理程序)。当然,如果你想为这个按钮添加其他点击事件处理程序(不是很频繁,但有时你可能想这样做),你应该谨慎使用它

另一种方法是每次按下下一个按钮时不添加click事件处理程序。只需在NextQuestion函数之外添加一次这样的事件(如果你想在文档就绪之外或在里面它并不重要)

$(document).on("click", "#submitBtn", function(e) {
    e.preventDefault();
    var options = $('.option');
    for (i = 0; i < options.length; i++) {
        var option = options[i];
        if ($(option).is(':checked')) {
            // console.log(option);
            userAnswerIndex = i;
            // validation
            Questions[n].validate(userAnswerIndex, keepScore);
        }
    }
});

    function nextQuestion(){
        // do everything else
    }

    var submitBtn = $('#submitBtn');
    submitBtn.on('click', function (e) {
        e.preventDefault();
        var options = $('.option');
        for (i = 0; i < options.length; i++) {
            var option = options[i];
            if ($(option).is(':checked')) {
                // console.log(option);
                userAnswerIndex = i;
                // validation
                Questions[n].validate(userAnswerIndex, keepScore);
            }
        }

    })