본문 바로가기

TIL/자바스크립트

addEventListener와 for, 이벤트리스너가 마지막 반복 결과값에만 붙는 문제 [자바스크립트]

카드퀴즈 만드는 중.

 

퀴즈의 선택지들을 찍어낸 뒤 각 선택지에 이벤트리스너를 붙이려 함.

function printChoices(questionIndex) {
  for (let i = 0; i < data[questionIndex].choices.length; i++) {
    document.getElementById('choices').innerHTML += `<div class="choice" id="question${questionIndex}Choice${i}">${data[questionIndex].choices[i]}</div>`;

    document.getElementById(`question${questionIndex}Choice${i}`).addEventListener('click', clickedChoice);
  }
}

그런데 마지막 선택지만 이벤트리스너가 붙는 문제 발생.

 

검색해보니 똑같은 문제에 부딪혔던 사례 발견.

https://stackoverflow.com/questions/36946159/adding-addeventlistener-in-loop-only-works-for-last-button

 

Adding addEventListener() in loop only works for last button

I get an json-array from dynamodb and is adding an addEventListener() to a button while traversing it. But only the last button responds to this. This has been asked before on SO and was the first...

stackoverflow.com

루프를 돌면서 innerHTML을 다시 찍어내는데 그때마다 기존 이벤트리스너가 지워졌던 것.

 

따라서 해결방법은 addEventListener를 반복문 밖으로 꺼내기. 즉 innerHTML을 모두 수정한 뒤에 별도 반복문으로 이벤트리스너 붙이기.

function printChoices(questionIndex) {
  for (let i = 0; i < data[questionIndex].choices.length; i++) {
    document.getElementById('choices').innerHTML += `<div class="choice" id="question${questionIndex}Choice${i}">${data[questionIndex].choices[i]}</div>`;

  for (let i = 0; i < data[questionIndex].choices.length; i++) {
    document.getElementById(`question${questionIndex}Choice${i}`).addEventListener('click', clickedChoice);
  }
}

 

더 공부할 내용..

https://gomakethings.com/why-you-shouldnt-attach-event-listeners-in-a-for-loop-with-vanilla-javascript/

 

Why you shouldn't attach event listeners in a for loop with vanilla JavaScript

Whenever I write about event delegation, I mention that you shouldn’t attach event listeners in a for loop (I also mention this in my pocket guide on DOM manipulation). To add the same event listener to multiple elements, you also cannot just use a for l

gomakethings.com

https://gomakethings.com/why-event-delegation-is-a-better-way-to-listen-for-events-in-vanilla-js/

 

Why event delegation is a better way to listen for events in vanilla JS

Yesterday, I shared my preferred approach to listening for click events with vanilla JavaScript: event delegation. When an element in the DOM is clicked, the event bubbles all the way up to the parent element (the document and then the window). This allows

gomakethings.com