<aside> 💡 이벤트 버블링/캡처링, stopPropagation(), preventDefault()까지 모두 실습할 수 있도록 작성함
</aside>
https://codepen.io/colorfilter/pen/rNmXxEe
<aside> <img src="/icons/search_gray.svg" alt="/icons/search_gray.svg" width="40px" />
이벤트 전파의 3단계
위 코드펜 예제에서 하단에 있는 <span> 태그를 클릭하면 span 영역 → p 영역 → div 영역 순으로 콘솔이 찍힌다. span 영역을 클릭한 순간 브라우저가 이벤트를 감지해서 문서 루트(window)까지 이벤트가 전달되는 것. 이것을 이벤트 버블링이라고 부른다.
이벤트 캡처링은 버블링 반대방향으로 진행된다. addEventListener() 3번째 인자를 true로 설정하면 되며, 이는 { capture: true }를 명시한 것과 같다. 기본값은 { capture: false } 이다.
<span> 태그를 클릭하면 div 영역 → p 영역 → span 영역 순으로 콘솔이 찍힌다. <span> 태그를 클릭한 순간 루트(window)부터 document → html → body → … 이벤트가 발생한 <span> 타깃 태그까지 내려가며 탐색하기 시작한다. 탐색하는 과정에서 중간에 거쳐가는 요소에 할당된 핸들러가 실행돼서 콘솔이 찍히는 것.
이벤트 버블링(Event Bubbling): 타깃 → 위
target(이벤트가 발생한 요소) → ... → body → html → document → window
이벤트 캡처링(Event Capturing): 위 → 타깃
window → document → html → body → ... → target(이벤트가 발생한 요소)
addEventListener() 3번째 파라미터가 캡처링 여부 결정
이벤트 버블링 : { capture: false } 혹은 false 혹은 아무것도 입력하지 않았을 때
// 아래 3개 동일
addEventListener('click', handler) // 3번째 인자에 아무것도 입력하지 않으면 버블링 기본
addEventListener('click', handler, false)
addEventListener('click', handler, { capture: false })
이벤트 캡처링 : { capture: true } 혹은 true
// 아래 2개 동일
addEventListener('click', handler, true)
addEventListener('click', handler, { capture: true })
addEventListener의 3번째 인자엔 capture외에 2가지 옵션이 더 있다.
once : 값 Boolean. true면 이벤트는 1번만 실행되고 리스너가 삭제된다
addEventListener('click', handler, { once: true }) // 혹은 { once: false }
passive : 값 Boolean. true면 이벤트 핸들러에 preventDefault()가 있어도 호출하지 않는다
preventDefault API 호출 여부를 명시하는 옵션이다. 브라우저는 기본적으로 preventDefault 호출 여부를 감시하는데, passive 속성을 true로 줌으로써 이런 감시 비용을 줄일 수 있다.
addEventListener('click', handler, { passive: true }) // 혹은 { passive: false }
<aside>
💡 명시하지 않았을 때 기본값은 false지만 wheel, mousewheel, touchstart, touchmove 이벤트에선 기본값이 true 인 점 주의(Safari, IE 제외) — [참고](https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener#:~:text=명시하지 않을 경우의 기본 값은 false지만%2C Safari와 Internet Explorer를 제외한 브라우저에서 wheel (en-US)%2C mousewheel (en-US)%2C touchstart%2C touchmove (en-US) 이벤트에서의 기본 값은 true입니다. 패시브 수신기로 스크롤 성능 향상에서 이 값에 대해 더 알아보세요.)
</aside>