javascript - 使用 JavaScript 的动态测验 - 添加一个 'back' 按钮

标签 javascript javascript-events

我是一名业余程序员,在 javascriptissexy's blog 上构建动态测验作为初学者类(class)的一部分|

我有一堆问题存储在这样的数组中:

 var allQuestions = [
{question: "Which of the following is true about a cat's whiskers?", choices: ["Unlike fur, they don't shed at all", "Defend against predators", "They work as sensors", "They serve no purpose at all"], correctAnswer: 2},
{question: "How are cats different from dogs?", choices: ["Cats have the ability to move in the air", "Cats are highly social animals", "Dogs are independent but cats are the opposite", "Dogs love children but cats dont"], correctAnswer: 0},
{question: "What is a sure way of getting a cat's attention if you don't have treats?", choices: ["Call its name", "Stimulate the cat's curiousity", "Cats never pay attention to humans", "Serve some vegetarian food"], correctAnswer: 1},
];

选择设置为 radio 输入。一次显示一个问题和选项。当用户单击下一步时,页面将显示数组中的下一组问题和选项。如果用户在没有做出选择的情况下单击下一步,则页面不会更新 - 会弹出一个警告,通知用户选择一个选项。在最后一个问题中,下一个按钮更改为“提交”,当用户点击提交时,将显示总分。

我的问题是我正在尝试添加一个“上一个”按钮,以便在单击时用户可以查看上一个问题(直到第一个问题)以及他们所做的选择,还可以更改他们的答案.我很难定义处理程序函数并跟踪上一个问题的答案。我是否需要使用闭包?

到目前为止,这是我的代码的链接:fiddle

最佳答案

有许多方法可以在这里发挥作用,但这里介绍一种方法。首先,跟踪用户提交的答案:

function collectUserAnswer() {
    allQuestions[pos].userAnswer =
        document.querySelector('input[name="choice"]:checked').value; 
}

然后,当您倒退时,您需要确保填写用户的答案(如果他们选择了一个):

function createChoices() {
    for(var i = 0; i < 4; i++) {
        var choice = document.getElementsByTagName("p")[i];
        var option = "<input id='ans_" + i 
            + "' type='radio' name='choice' value='" 
            + i + "'";

        if ( i == allQuestions[pos].userAnswer ) {
            option += " checked='checked'";   
        }
        option +=  ">" + allQuestions[pos].choices[i] 
               + "</input>";

        choice.innerHTML = option;
    }
}

当您计算分数时,不必跟踪总计会更容易。对于运行总计,您有一组逻辑需要在用户向前导航时发生,而另一组逻辑则在用户向后导航时发生。相反,我们可以使用一组逻辑来每次计算整个分数:

function calcScore() {
    var score = 0;
    for ( var i = 0; i < allQuestions.length; i++ ) {
        if ( allQuestions[i].userAnswer == allQuestions[i].correctAnswer ) {
            score++;
        }
    }
    this.totalScore = score;
}

接下来,您必须根据当前选择的问题复制创建正确按钮的逻辑,并将其放入 updatePrevious() 函数中。但是每当我看到代码重复时,我认为这是一个很好的机会,可以将重复的代码拆分成它自己的函数,这样我就可以重用它而不用重复它。这样,如果您在该代码中发现错误,则不必找到所有将错误复制到的地方并在所有这些地方修复它。所以,我会这样分解:

function updateNavigationButtons() {
    if(pos < len) {
        createQuestion();
        createChoices();
        submitButton.innerHTML = '<input id="next" type="button" name="nextbutton" value="Next Question" onclick="updateNext();"><input id="back" type="button" name="backbutton" value="Previous Question" onclick="updatePrevious();">';
    }
    if(pos == len-1) {
        submitButton.innerHTML = '<input id="submit" type="button" name="submitbutton" value="Submit Quiz" onclick="updateNext();"><input id="back" type="button" name="backbutton" value="Previous Question" onclick="updatePrevious();">';
    }
    if(pos == len) {
        while(firstDiv.hasChildNodes()) {
            firstDiv.removeChild(firstDiv.lastChild);
        }
        submitButton.innerHTML = "Your total score: " + this.totalScore; 
    }
}

最后,您需要确保您的上一个和下一个按钮处理程序调用新的 updateNavigationButtons() 函数:

//update when user clicks next question
function updateNext() {
    displayAlert();  
    collectUserAnswer();
    calcScore();
    pos++;
    updateNavigationButtons();
};

//update when user clicks previous question
function updatePrevious() {
    displayAlert();  
    collectUserAnswer();
    calcScore();
    pos--;
    updateNavigationButtons();
}

我还有很多方法可以改进这段代码。 updateNext()updatePrevious() 除了它们对 pos 变量的处理外,它们看起来几乎相同;所以你可能想尝试找到一种方法来消除代码重复。在开始之前,我注意到向后导航仍然存在错误——如果没有选择答案,则会发生错误。

但希望这能让你更接近一点。可以找到我更改的 fiddle here .

关于javascript - 使用 JavaScript 的动态测验 - 添加一个 'back' 按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22206222/

相关文章:

javascript - 如何遍历表并从行中提取值并与数据表进行比较

javascript - jQuery Spritely 插件不适用于 jQuery + 1.11

javascript-events - 事件处理问题 (Javascript)

javascript - 如何将 this 上下文传递给事件处理程序?

javascript - 我的 Greasemonkey 脚本开始加载一系列图像。当需要时我该如何停止它?

Javascript 获取原始浏览器宽度或分辨率

javascript - 在自动模式下关注网格中的新行

javascript - document.onclick 与 window.onclick

javascript - Event.target、Event.toElement 和 Event.srcElement 之间有什么区别?

javascript-events - SproutCore以编程方式触发MenuPane中的项目选择