이벤트 전파(버블링, 캡처링), 이벤트 위임 정리

rkdghwnd·2023년 5월 22일
0

이벤트 전파

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});

이벤트 전파 방지하는 방법

  1. event.stopPropagtion()
    버블링 또는 캡처링 설정에 따라 상위, 하위로 가는 이벤트 전파를 막을 수 있다.
    다만 이벤트에 등록된 핸들러가 여러개인 경우, 다른 형제 핸들러가 동작하는건 막지 못한다.
child.addEventListener("click", (e) => {
  e.stopPropagation() // 이벤트 전파 방지
  print('ancestor')
})

child.addEventListener("click", (e) => {
  print('parent') // 실행 됨
})

child.addEventListener("click", (e) => {
  print('child') // 실행 됨
})
  1. e.stopImmediatePropagation()
    이벤트 전파를 막되, 다른 형제 핸들러가 동작하는 것까지 막아준다.
child.addEventListener("click", (e) => {
    
    if(조건)
    	e.stopImmediatePropagation()
      
    print('child')
})

child.addEventListener("click", (e) => {
    print('child 2') // e.stopImmediatePropagation() 인해 실행 안됨
})
  1. e.target 으로 조건 걸어 방지
    e.target이 누구인지에 따라 분기를 나누어 실행 될것과 실행되지 않을것을 정하면, 직접적으로 이벤트 전파를 막지 않아도, 이벤트 전파로 인해 의도하지 않은 동작을 방지할수 있다.
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)'이 되어리기 때문에 분석이 제대로 되지 않을 수 있다.

따라서 꼭 필요한 경우를 제외하곤 버블링을 막지 않는 것이 좋다. 대부분의 경우는 버블링을 막지 않고 커스텀 이벤트를 활용해 문제를 해결할수 있다고 한다.

profile
rkdghwnd's dev story

0개의 댓글