在JavaScript

时间:2017-02-14 10:07:05

标签: javascript

我遇到的问题是尝试在JavaScript测验的预制框中动态生成答案。每个答案都有一个索引,它是确定答案是否正确的索引(此信息来自JSON,无法修改)。对于每个问题,答案都是随机的。我还有一个单独的功能,如果他们是对或错,反馈给用户。

我最初使用For循环来动态构建每个答案的方法,但这是在每个答案中加载相同的索引(在for循环中使用变量时常见的问题)。所以我决定为每个答案添加一个监听器,并将其拉出一个单独的函数,以确保每个答案都有自己的索引。这部分工作得很好,每个都有自己的监听器将索引传递给答案函数,但是当下一个问题被加载时,两个监听器已被添加到答案中,因为它是为下一个问题重新生成的。所以,从逻辑上讲,我添加了一个删除侦听器,但这似乎不起作用。

我知道我需要做些什么来使这个测验工作,我只是不知道该怎么做。这是我已有的代码:

将答案加载到屏幕:

// Load Answers
for (i=0; i<4; i++) {
    var answerBox = 'answer' + (i + 1);
    app.LoadInnerHTML(answerBox, answers[i].title);
    this.listenerFunc(i);
}

添加听众:

this.listenerFunc = function(j) { 
        var thisQuiz = this;
        var answers = this.CurrentAnswers;
        var answerBox = 'answer' + (j + 1);
        var answerIndex = answers[j].index;
        var answerElement = document.getElementById(answerBox);
        // If there already is an event listener then remove it
        answerElement.removeEventListener('click', function () {
                thisQuiz.AnswerQuestion(answerIndex);
        });
        // Add New Event Listener
        if (answerElement.addEventListener) {  // all browsers except IE before version 9
            answerElement.addEventListener("click", function () {
                thisQuiz.AnswerQuestion(answerIndex);
            }, false);
        } else {
            if (answerElement.attachEvent) {   // IE before version 9
                answerElement.attachEvent("click", function () {
                    thisQuiz.AnswerQuestion(answerIndex);
                });
            }
        }
    };

回答问题:

// Answer Questions
    this.AnswerQuestion = function (index) {
        // If Question is answered correctly
        if (index == 0) {
            alert('Question Answered Correctly ' + index);
        } else {
            alert('Question Answered Incorrectly ' + index);
        }
        // Call Next Question
        this.LoadNextQuestion();
    }

我觉得我需要解开所有问题,因为我一直在修补它以试图让它发挥作用。虽然我只能使用JavaScript,但我不能使用像JQuery这样的任何框架 - 我很确定它是JQuery中一个非常简单的解决方案,但不幸的是我只能使用JavaScript。

1 个答案:

答案 0 :(得分:1)

问题在于将闭包传递给removeEventListener。这是对回调的全新引用,因此浏览器无法将其删除,因为它未在侦听器列表中定义。

您需要从外部(远离listenerFunc)提取一个侦听器列表:

this.listenerCallbacks = [];

this.listenerFunc = function(j) { 
        // .. head of listenerFunc

        var answerIndex = answers[j].index;

        if (!this.listenerCallbacks[answerIndex]) {
                this.listenerCallbacks[answerIndex] = function () {
                        thisQuiz.AnswerQuestion(answerIndex);
                }
        }

        var answerElement = document.getElementById(answerBox);

        // If there already is an event listener then remove it
        answerElement.removeEventListener('click', this.listenerCallbacks[answerIndex]);

        // Add New Event Listener
        if (answerElement.addEventListener) {  // all browsers except IE before version 9
            answerElement.addEventListener("click", this.listenerCallbacks[answerIndex], false);
        } else if (answerElement.attachEvent) {   // IE before version 9
            answerElement.attachEvent("click", this.listenerCallbacks[answerIndex]);
        }
    };