addEventListener 세 번째 인자, 왜 중요한가?

Jina·2025년 10월 18일
post-thumbnail

🎯 addEventListener

element.addEventListener(type, listener, options);

addEventListener의 세 번째 인자는 옵션이며, 아래 두 가지 형태로 쓸 수 있다.

  • 단순히 true 또는 false
  • 혹은 { capture: true, once: false, passive: false } 같은 객체 형태

1️⃣ 이벤트 전파(Event Propagation)의 두 단계

브라우저에서 이벤트가 발생하면, 두 가지 방향으로 전파된다.

단계설명예시
캡처링 (capturing)이벤트가 최상위 요소(document)에서 시작해 타깃 요소까지 내려감부모 → 자식 순서
버블링 (bubbling)이벤트가 타깃 요소에서 다시 부모로 올라감자식 → 부모 순서

즉, 하나의 클릭이 발생해도
→ 캡처링 단계에서 부모들이 먼저 감지하고
→ 그다음에 타깃과 그 부모들이 버블링 단계에서 다시 감지한다.


2️⃣ addEventListener의 세 번째 인자 의미

✅ false (기본값)

이벤트를 버블링 단계에서 감지한다.
즉, 이벤트가 타깃까지 도달한 뒤 위로 올라올 때 실행된다.

element.addEventListener('click', handler, false);

✅ true

이벤트를 캡처링 단계에서 감지한다.
즉, 이벤트가 타깃으로 내려가는 도중에 실행된다.

element.addEventListener('click', handler, true);

3️⃣ 실전 예제

<div id="parent">
  PARENT
  <button id="child">CHILD</button>
</div>

<script>
  const parent = document.querySelector('#parent');
  const child = document.querySelector('#child');

  parent.addEventListener('click', () => {
    console.log('👨‍👩‍👧 parent clicked');
  }, false); // 기본값: 버블링

  child.addEventListener('click', () => {
    console.log('🧒 child clicked');
  }, true); // 캡처링
</script>

실행 순서

  1. 캡처링 단계(true) → child가 먼저 감지됨
  2. 그 후 버블링 단계(false) → parent가 감지됨

콘솔:

🧒 child clicked
👨‍👩‍👧 parent clicked

만약 반대로 parent의 세 번째 인자를 true로 하면
부모가 먼저 찍히고 자식이 나중에 찍힌다.


4️⃣ 왜 true를 넣었더니 동작했을까?

보통 이런 상황은 다음과 같은 경우다.

  • 버블링 단계에서는 이미 이벤트가 중단(stopPropagation) 되었던 경우
    → 부모 요소에 false(기본값)로 등록하면 이벤트가 거기까지 "도달"하지 않음.
    → 하지만 true로 등록하면 캡처링 단계에서 이미 감지하기 때문에 이벤트가 "막히기 전에" 실행됨.

예를 들어,

child.addEventListener('click', e => e.stopPropagation());
parent.addEventListener('click', () => console.log('parent'), true);

이럴 땐 true를 넣은 부모 핸들러만 실행된다.
이벤트 전파의 방향을 바꿔서 막힘을 우회한 것.


5️⃣ 객체 형태 옵션 더 알아보기

ES6 이후부터는 세 번째 인자 대신 객체를 넘길 수도 있다.

element.addEventListener('click', handler, {
  capture: true,
  once: true,    // 한 번만 실행 후 자동 제거
  passive: true, // preventDefault() 호출 불가 (스크롤 성능 향상)
});

가장 많이 쓰이는 건 capture, once, passive 세 가지.

옵션설명기본값
capturetrue면 캡처링 단계에서 실행false
once한 번 실행 후 자동 제거false
passivepreventDefault() 비활성화false

💡 마무리

“addEventListener는 그냥 이벤트 등록하는 함수잖아?”
→ 맞아, 하지만 세 번째 인자 하나로 이벤트 흐름 전체가 바뀐다.

profile
즐겁게 코딩하고 공부해요🍀

0개의 댓글