在JavaScript中添加/删除动态生成的事件
我遇到的问题是,尝试将答案动态生成到预先制作的框中,以便进行JavaScript测试。每个答案都有一个索引,该索引确定答案是否正确(此信息来自JSON,无法修改)。对于每个问题,答案都是随机的。我也有一个单独的功能,反馈给用户,如果他们是对的或错的 我最初采用的方法是使用for循环来动态构建每个答案,但这是在每个答案中加载相同的索引(在for循环中使用变量是一个常见问题)。所以我决定为每个答案添加一个侦听器,并将其拉入一个单独的函数中,以确保每个答案都有自己的索引。这一部分工作得很好,每个部分都有自己的侦听器将索引传递给应答函数,但是当加载下一个问题时,在为下一个问题重新生成答案时,两个侦听器被添加到了答案中。所以,从逻辑上讲,我添加了一个remove侦听器,但这似乎不起作用 我知道我需要做些什么才能让这个测验有效,我只是不知道怎么做。以下是我已经掌握的代码: 将答案加载到屏幕:在JavaScript中添加/删除动态生成的事件,javascript,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);
}
回答问题:
// 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]);
}
};