DOM 요소 에서 발생한 이벤트는 DOM 트리를 통해 전파되는 특성이 있다.
이를 이벤트 전파(event propagtion)이라고 하는데 다음과 같은 단계으로 이루어진다.
1. 캡처링 단계(capturing phase) : 이벤트가 상위 요소에서 하위 요소로 전파
2. 타깃 단계(target phase) : 이벤트가 해당 타깃에 도달
3. 버블링 단계(bubbling phase) : 이벤트가 하위 요소에서 상위 요소로 전파
대부분의 이벤트는 버블링 방식으로 전파된다. 다만 addEventListener()
방식으로 이벤트를 지정하면 기본적으로 버블링 방식을 전파되며 세번째 요소에 true를 주여 버블링에서 캡처링으로 전파방식을 변경할 수 있다.
element.addEventListener('click', (e) => { ... }, false); // 버블링 전파로 설정
element.addEventListener('click', (e) => { ... }, true); // 캡처링 전파로 설정
element.addEventListener('click', (e) => { ... }, {capture: true});
child.addEventListener("click", (e) => {
e.stopPropagation() // 이벤트 전파 방지
print('ancestor')
})
child.addEventListener("click", (e) => {
print('parent') // 실행 됨
})
child.addEventListener("click", (e) => {
print('child') // 실행 됨
})
child.addEventListener("click", (e) => {
if(조건)
e.stopImmediatePropagation()
print('child')
})
child.addEventListener("click", (e) => {
print('child 2') // e.stopImmediatePropagation() 인해 실행 안됨
})
document.body.addEventListener('click', (e) => {
if (e.target.id === "ancestor") {
print('ancestor')
}
if (e.target.id === "parent") {
print('parent')
}
if (e.target.id === "child") {
print('child')
}
});
버블링 이벤트 전파를 막는 e.stopPropagation()
메서드는 추후에 문제가 되는 상황이 생길 수 있다.
사람들이 페이지에서 어디를 클릭했는지 등의 행동 패턴을 분석하기 위해, window 내에서 발생하는 클릭 이벤트 전부를 감지는 분석 시스템을 사용할때, 이런 분석 시스템의 코드는 클릭 이벤트를 감지하기 위해 보통 document.addEventListener('click') 와 같이 사용하는데, stopPropagation로 버블링을 막아놓은 영역에선 '죽은 영역(dead zone)'이 되어리기 때문에 분석이 제대로 되지 않을 수 있다.
따라서 꼭 필요한 경우를 제외하곤 버블링을 막지 않는 것이 좋다. 대부분의 경우는 버블링을 막지 않고 커스텀 이벤트를 활용해 문제를 해결할수 있다고 한다.