我遇到的问题是尝试在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。
答案 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]);
}
};