2017-02-14 3 views
0

Проблема, с которой я столкнулась, заключается в том, чтобы динамически генерировать ответы в готовых полях для викторины JavaScript. Каждый ответ имеет индекс, и именно индекс определяет, соответствует ли ответ (эта информация поступает из JSON и не может быть изменена). Для каждого вопроса ответы все рандомизированы. У меня также есть отдельная функция для обратной связи с пользователем, если они были правильными или неправильными.Добавление/удаление динамически сгенерированных событий в JavaScript

Подход, с помощью которого я начал использовать For Loop для динамического построения каждого ответа, но он загружал один и тот же индекс в каждый ответ (общая проблема при использовании переменных внутри циклов). Поэтому я решил добавить слушателя к каждому ответу и вытащил его в отдельную функцию, чтобы каждый ответ имел свой собственный индекс. Эта часть работала отлично, каждый из них имел свой собственный слушатель, передающий индекс функции ответа, но когда следующий вопрос был загружен, два слушателя были добавлены в ответ, поскольку он был сгенерирован для следующего вопроса. Итак, логически я добавил прослушиватель удаления, но это, похоже, не работает.

Я знаю, что мне нужно сделать, чтобы сделать эту работу викторины, я просто не знаю, как это сделать. Вот код, который я уже:

Загрузка Ответы на экране:

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

Пожалуйста, предоставьте «Minimal, полный и проверяемый пример»: http://stackoverflow.com/help/mcve – Connum

+0

Вот и все, что у меня есть, имеет отношение к проблеме, я ничего не могу вам показать ... –

+0

Не совсем понятно, почему вы делаете то, что делаете, и может ли быть лучший способ добиться того, что вы пытаетесь, без видя структуру JSON и HTML пары вопросов/ответов. – Connum

ответ

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]); 
     } 
    }; 
+0

Это все еще дает мне несколько слушателей, к сожалению - это прослушиватель, который не работает по какой-то причине –

+0

Вы проверяли, хранятся ли слушатели в 'listenersCallbacks'? Вы пробовали проверять связанных слушателей событий на элементе в консоли разработчика? Также - на каком браузере вы тестируете? – radmen

+0

СлушателиCallbacks содержат четыре экземпляра 'QuizBase/this.listenerFunc/this.listenerCallbacks [answerIndex]()' - Я тестирую последнюю версию Firefox. –

Смежные вопросы