<aside> 💡 이벤트 버블링/캡처링, stopPropagation(), preventDefault()까지 모두 실습할 수 있도록 작성함
</aside>
https://codepen.io/colorfilter/pen/rNmXxEe
위 코드펜 예제에서 하단에 있는 span
태그를 클릭하면 ➊ "span 영역" → ➋ "p 영역" → ➌ "div" 영역 순으로 콘솔이 찍힌다. span 영역을 클릭한 순간 브라우저가 이벤트를 감지해서 최상위에 있는 요소까지 이벤트가 전달되는 것. 이것을 이벤트 버블링이라고 부른다.
이벤트 캡처링은 버블링 반대방향으로 진행된다. addEventListener()
3번째 인자에 true
를 명시하면 된다. 이는 { capture: true }
를 명시한 것과 같다. 기본 값은 { capture: false }
다.
하단의 span
태그를 클릭하면 콘솔에 ➊ "div 영역" → ➋ "p 영역" → ➌ "span" 영역 순으로 콘솔이 찍힌다. <span>
태그를 클릭한 순간 최상위 요소 <html>
태그부터 이벤트가 발생한 <span>
태그까지 내려가며 탐색하기 시작한다. 탐색하는 과정에서 중간을 거치는 요소에 할당된 핸들러가 실행돼서 콘솔이 찍히는 것.
이벤트 버블링(Event Bubbling) : 아래 → 위
target
(이벤트가 발생한 요소) → ... → body
→ html
이벤트 캡처링(Event Capturing): 위 → 아래
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>
이벤트 리스너를 제거할 때 removeEventListener
메서드를 사용한다. 주의할 점은 이벤트를 등록했을 때의 핸들러(콜백)와, capture
리스너 옵션(리스너 3번째 매개변수) 값이 일치해야만 제거된다. 따라서 이벤트 리스너를 제거할 땐 이벤트를 등록했을 때와 동일한 핸들러와 capture
옵션을 명시해야 한다.