표준 DOM 이벤트에서 정의한 이벤트 흐름의 3가지 단계
- 캡처링 단계 – 이벤트가 하위 요소로 전파되는 단계 (false가 기본)
- 타깃 단계 – 이벤트가 실제 타깃 요소에 전달되는 단계
- 버블링 단계 – 이벤트가 상위 요소로 전파되는 단계
이벤트 버블링 (- 거의 모든 이벤트의 특징)
- 특정 엘리먼트에 이벤트가 발생하면 해당 이벤트가 그 엘리먼트의 조상들에게 까지 위로 전달되는 현상
- 즉 자식 eventListener를 등록시켰다면, 자식 이벤트 발생 후에 부모 이벤트도 같이 발생된다.
- capture가 false인 것만 실행된다
- 요소
event.target
: 이벤트가 발생한 가장 안쪽의 요소- 부모 요소의 핸들러는 이벤트가 정확히 어디서 발생했는지 등에 대한 자세한 정보를 얻을 수 있다.
event.currentTarget
: 현재 실행 중인 핸들러가 할당된 요소currentTarget
요소를 정확히 클릭했을 때는,target
과currentTarget
가 같다
- 버블링 중단
event.stopPropagation()
를 이벤트에 등록하면, 해당 이벤트 동작 시 부모 이벤트는 발생하지 않는다.event.stopImmediatePropagation()
: 해당 이벤트 뿐만 아니라, 해당 요소에 등록된 다른 이벤트도 버블링이 중단된다.- 이벤트 버블링을 막아야 하는 경우는 거의 없다. 버블링을 막아야 해결되는 문제라면 커스텀 이벤트 등을 사용해 문제를 해결할 수 있다.
이벤트 캡쳐링
- 이벤트가 하위 요소로 전파되는 현상
- false가 디폴트 값
- 캡처링 단계에서 이벤트를 잡아내려면
addEventListener
의capture
옵션을true
로 설정해야 함 elem.addEventListener(..., {capture: true})
{capture: true} 대신 true만 적어줘도 됨
event.eventPhase
– 현재 이벤트 흐름 단계(캡처링=1, 타깃=2, 버블링=3) - 자주 사용되진 않음
이벤트 위임
- 이벤트 버블링과 캡쳐링을 활용한 이벤트 핸들링 패턴
- 요소마다 핸들러를 할당하지 않고, 요소의 공통 조상에 이벤트 핸들러를 단 하나만 할당해도 여러 요소를 한꺼번에 다룰 수 있다.
- 알고리즘
- 컨테이너에 하나의 핸들러를 할당
- 핸들러의
event.target
을 사용해 이벤트가 발생한 요소가 어디인지 알아냄 - 원하는 요소에서 이벤트가 발생했다고 확인되면 이벤트를 핸들링
- 이후에 child-element를 추가해도 이 새로운 요소에 이벤트 핸들러를 바인딩 할 필요가 없음(event처리는 parent-element로 위임되었기 때문)
- 이벤트 위임을 사용하려면 이벤트가 반드시 버블링 되어야한다.
elem.closest(selector)
:elem
의 상위 요소 중selector
와 일치하는 가장 근접한 조상 요소를 반환
element.tagName
: 엘리먼트(태그)의 이름
- 배열의 메서드인
indexOf
를 이용해서, querySelector에서 찾은 배열 중event.target의 인덱스를 찾는다.
- 핸들러를 제거할 때
addEventListener
와removeEventListener
는 같은 단계에 있어야 한다.