Javascript

Label 태그를 클릭했는데 클릭이 두 번

gilchris 2023. 4. 13. 23:40

이런 HTML과

<form>
  <div id="my-test">
    <input type="checkbox" id="my-checkbox" />
    <label for="my-checkbox">체크</label>
  </div>
  <div id="output"></div>
</form>

이런 Javascript가 있을 때,

const outEl = document.querySelector('#output');
document.querySelector('#my-test').addEventListener('click', () => {
  outEl.innerHTML += 'click!!!<br/>';
});

'체크'라는 글씨를 클릭하면 output에 click!!!이 두 번 찍힌다.

이런 일이 발생하는 이유는 label 태그를 클릭하면 label 태그의 for 속성과 연결된 input tag에서 자동으로 클릭 이벤트가 발생하기 때문이다.

그래서 label을 클릭하면 ->  event bubbling에 따라서 div#my-test에 클릭이 발생하고(click!!!을 한 번 찍고) -> 자동으로 for 속성에 ID값으로 연결된 input#my-checkbox에 클릭 이벤트가 발생하고 다시 event bubbling으로 div#my-test에 클릭 이벤트가 전달(click!!!을 또 찍음)되는 순서로 이벤트가 전달된다.

이를 가장 손쉽게 막는 방법은 event bubbling을 막는 것이다.

const outEl = document.querySelector('#output');
document.querySelector('#my-test').addEventListener('click', (event) => {
  event.stopPropagation(); // 여기에서 event bubbling을 막는다.
  outEl.innerHTML += 'click!!!<br/>';
});

하지만 대부분의 경우에는 진짜로 클릭이 발생했는지를 알고 싶다기 보단 저 input 태그 값에 변화가 생겼는지 알기 위함이었을 것이다.

그러니 명확하게 input 태그에 change 이벤트를 받는 것이 낫다.

const outEl = document.querySelector('#output');
document.querySelector('#my-checkbox').addEventListener('change', (event) => {
  outEl.innerHTML += 'change!!!<br/>';
});

참고