объектно-ориентированное приложение для викторины - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь создать простое приложение для викторин с использованием javascript, и все идет хорошо, но когда дело доходит до проверки, происходит что-то странное, он проверяет мой код дважды! Один раз с правильным ответом на предыдущий вопрос, а другой раз с правильным для текущего! Кто-нибудь может проверить мой код? Находит, где ошибка? Большое спасибо

(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-разметка, еще раз спасибо --->

<!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 голосов
/ 25 апреля 2018

Ваша проблема заключается в том, что каждый раз, когда пользователь нажимает следующую кнопку, к кнопке отправки добавляется новый обработчик события щелчка.на самом деле делают это снова и снова.Если пользователь трижды щелкнет следующую кнопку перед отправкой, он трижды активирует функцию проверки и т. Д. ...

Вы можете справиться с этим, удалив все остальные обработчики событий щелчка каждый раз, когда добавляете событие,(Самый простой) Вы можете сделать это с помощью jquery off , например,

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

, где вы просто отвязываете все обработчики событий щелчка, прежде чем добавить свой новый.(Таким образом, вы всегда будете иметь обработчик событий одним кликом на кнопке отправки).Конечно, если вы хотите добавить к этой кнопке другие обработчики событий щелчка (не очень часто, но, возможно, иногда вы хотите это сделать), вы должны использовать это с осторожностью

Другой способ - просто не добавлять событие щелчкаобработчик каждый раз, когда нажимается следующая кнопка.Просто добавьте событие один раз за пределы вашей функции 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);
            }
        }

    })
0 голосов
/ 25 апреля 2018

Я не смог выполнить код, чтобы быть уверенным, поскольку у меня не было соответствующей разметки, но при чтении кажется, что проблема может быть в этом блоке кода

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') содержит только один выбранный элемент. Но если у вас есть несколько элементов select или input с классом option и пользователь выбрал несколько из них, вы можете получить более одного выбранного элемента. В этом случае вы можете увидеть, что вопрос проверяется более одного раза

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...