HTML Event Flow

김병엽·2024년 7월 8일

HTML Event Flow

  • HTML 문서의 각 엘리먼트들은 아래와 같이 태그 안의 태그가 위치하는 식으로 계층적으로 이루어짐.

  • 이러한 계층적 구조 특징 때문에 만일 HTML 요소에 이벤트가 발생할 경우 연쇄적 이벤트 흐름이 일어남.


예를들어 아래 3개가 중첩된 박스 영역에서 가장 자신 엘리먼트인 p 박스를 클릭하면 onclick 이벤트 스크립트가 p 뿐만 아니라 그의 부모인 div와 form 엘리먼트도 발생함을 볼 수 있다.

이러한 현상을 이벤트 전파(Event Propagation)라 부르며, 전파 방향에 따라 버블링과 캡처링으로 구분한다

What is the Event bubbling?

  • 특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되어 가는 특성을 의미.

What is the Event capture?

  • 캡쳐링은 반대로 브라우저로부터 이벤트가 발생한 요소까지 이벤트를 전달.
    이벤트 버블링과 정반대인 것.

Controlling Event Propagation

  • 만일 부모와 자식 둘다 이벤트를 등록한 상태에서, 자식 요소만 클릭했을때만 이벤트를 발생하고 부모 요소는 이벤트를 발생시키고 싶지 않은 상황이 발생.

  • 브라우저의 이벤트 구조를 바꿀수는 없고, 엘리먼트의 이벤트 전파를 방지 처리 하는 식으로 해결.

1. stopPropagation()

  • 버블링 또는 캡처링 설정에 따라 상위, 하위로 가는 이벤트 전파를 제어.
ancestor.addEventListener("click", (e) => {
  e.stopPropagation() // 이벤트 전파 방지
  print('ancestor')
})

parent.addEventListener("click", (e) => {
  e.stopPropagation() // 이벤트 전파 방지
  print('parent')
})

child.addEventListener("click", (e) => {
  e.stopPropagation() // 이벤트 전파 방지
  print('child')
})


2. stopImmediatePropagation()

  • 이벤트 전파와 더불어 형제 이벤트 실행을 중지.
child.addEventListener("click", (e) => {
    
    if(조건)
    	e.stopImmediatePropagation()
        
    print('child')
})

child.addEventListener("click", (e) => {
    print('child 2')
})
/// child

3. 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')
    }
    
});

4. preventDefault()

  • 이벤트 전파 뿐만 아니라 기본 이벤트 동작 자체를 취소.

이벤트 전파 제어 주의점


서비스에서 사람들이 페이지에 어디를 클릭했는지 등의 행동 패턴을 분석하기 위해, window 내에서 발생하는 클릭 이벤트 전부를 감지는 분석 시스템을 사용할때, 이런 분석 시스템의 코드는 클릭 이벤트를 감지하기 위해 보통 document.addEventListener('click') 와 같이 사용하는데, stopPropagation로 버블링을 막아놓은 영역에선 '죽은 영역(dead zone)'이 되어버리기 때문에 분석이 제대로 되지 않을 수 있다.

따라서 꼭 필요한 경우를 제외하곤 버블링을 막지 않는 것이 좋다.
아키텍처를 잘 고려해 진짜 막아야 하는 상황에서만 버블링을 막아야 한다.


Reference

MDN
https://sangjuntech.tistory.com/22

profile
선한 영향력을 줄 수 있는 개발자가 되자, 되고싶다.

0개의 댓글