Usuwanie eventListener z pętli

0

Cześć wszystkim,
tworzę prostą quiz apke i chciałbym aby po wybraniu jakiejkolwiek odpowiedzi, zablokować możliwość wybranie jakiejkolwiek innej. Niżej kodzik by wyjaśnić o co mi chodzi:

        const answers = document.querySelectorAll('.answer');
        answers.forEach((answer, index) => {
            const checkAnswer = () => {
                const correctAnswer = convertLetterToIndex();
                if (index === correctAnswer) {
                    answer.classList.add('correct');
                }
                else {
                    answer.classList.add('incorrect');
                }
                answers[0].removeEventListener('click', checkAnswer); //nie działa
            }
            answer.addEventListener('click', checkAnswer);
        });
0

@Xarviel: Dlatego bo chce usunąć listener z jakiejkolwiek odpowidzi (nawet wszyskich naraz) przy wybraniu jakiejkolwiek innej

0

Zapis answers[0].removeEventListener('click', checkAnswer); powinien działać, ale jedynie dla pierwszego elementu.
Żeby odpiąć zdarzenie wszystkim checkboxom musisz ponownie zrobić pętle z removeEventListener

const answers = document.querySelectorAll('.answer');

answers.forEach((answer, index) => {
  const checkAnswer = () => {
    const correctAnswer = convertLetterToIndex();
    
    if (index === correctAnswer) {
      answer.classList.add('correct');
    }
    else {
      answer.classList.add('incorrect');
    }

    answers.forEach(oldAnswer => {
      oldAnswer.removeEventListener('click', checkAnswer);
    });
  }
  answer.addEventListener('click', checkAnswer);
});
0

@Xarviel: Właśnie mimo to nie działa. Tak jak napisałeś i dokładnie o to mi chodzi, ale jednak dalej działają clicki na pozostałych

1

Trzeba przenieść funkcję checkAnswer poza pętle, ponieważ za każdym razem tworzona jest nowa referencja do funkcji i przez to metoda removeEventListener nie może odnaleźć prawidłowego eventu, a parametry answer i index, powinny być zdefiniowane niezależnie od pętli, więc zamieniłem answer na e.target, a index na e.target.dataset.index

const answers = document.querySelectorAll('.answer');

const checkAnswer = (e) => {
  const correctAnswer = convertLetterToIndex();
  const index = e.target.dataset.index;

  if (index === correctAnswer) {
    e.target.classList.add('correct');
  }
  else {
    e.target.classList.add('incorrect');
  }

  answers.forEach(oldAnswer => {
    oldAnswer.removeEventListener('click', checkAnswer);
  });
}
  
answers.forEach((answer, index) => {
  answer.dataset.index = index;
  answer.addEventListener('click', checkAnswer);
});
0

@Xarviel: O proszę. Do końca życia zapamiętam dataset :D Tak jak napisałeś też podejrzewałem, ze tworzenie funkcji w pętli powoduje tworzenie jej kilka razy i dlatego nie jest w stanie odnaleźć, którą tak naprawdę ma odpiąć, ale nie miałem żadnego pomysłu jak odpiąć funkcję poza pętlą z danego elementu. Dataset wszystko rozwiązuje. Dzięki wielkie!

1

Fajnie, że zadziałało :).
Można też odczytywać jakieś niestandardowe atrybuty zdefiniowane w html

<input type="checkbox" data-index="2">
const checkbox = document.querySelector('input');
console.log(checkbox.dataset.index);

1 użytkowników online, w tym zalogowanych: 0, gości: 1