在JavaScript中添加/删除动态生成的事件

在JavaScript中添加/删除动态生成的事件,javascript,Javascript,我遇到的问题是,尝试将答案动态生成到预先制作的框中,以便进行JavaScript测试。每个答案都有一个索引,该索引确定答案是否正确(此信息来自JSON,无法修改)。对于每个问题,答案都是随机的。我也有一个单独的功能,反馈给用户,如果他们是对的或错的 我最初采用的方法是使用for循环来动态构建每个答案,但这是在每个答案中加载相同的索引(在for循环中使用变量是一个常见问题)。所以我决定为每个答案添加一个侦听器,并将其拉入一个单独的函数中,以确保每个答案都有自己的索引。这一部分工作得很好,每个部分都

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

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

我知道我需要做些什么才能让这个测验有效,我只是不知道怎么做。以下是我已经掌握的代码:

将答案加载到屏幕:

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

// 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。

问题在于将闭包传递给
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]);
        }
    };

请提供一个“最小的、完整的、可验证的例子”:这就是我所拥有的与问题相关的所有东西,我无法向你展示任何其他东西……你为什么要这样做,以及是否有更好的方法来实现你所尝试的,没有看到JSON结构和问答对的HTML。不幸的是,这仍然给了我多个侦听器-由于某些原因,删除侦听器不起作用。您是否检查了侦听器是否存储在
侦听器ScalBacks
?您是否尝试过在开发人员控制台中的元素上检查绑定事件侦听器?另外-您在哪个浏览器上测试?ListenerScalBacks包含四个
QuizBase/this.listenerFunc/this.listenerCallbacks[answerIndex]()
-我在最新版本的Firefox上测试,
answerIndex
在调用
listenerFunc
时是否会改变
j
参数的值?对我来说,为给定答案的回调保留引用似乎有问题。是的,每次调用listenerFunc时,答案索引都会更改-因此答案索引将以0-3的任意顺序不同步,但j是顺序的
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]);
        }
    };