UX TECH TF 업무에서 DOM과 이벤트를 다루는 일이 많은데요,
이벤트 버블링, 캡쳐링 공부한 후 정리한 내용을 공유드리고자 합니다.
버블링
Element1 요소안에 Element2가 있고 두 요소에는 모두 클릭 이벤트 핸들러가 있습니다.
사용자가 Element2를 클릭하면 Element1, Element2 두군데 모두에서 이벤트가 실행 됩니다.
어떤 이벤트가 먼저 실행 될까요?
jsfiddle에서 확인 해주세요!
이벤트 전달 및 흐름
표준 DOM 이벤트에서 정의한 이벤트 흐름에는 3가지 단계가 있습니다.
- 캡쳐링 단계: 이벤트가 하위 요소로 전파되는 단계
- 타깃 단계: 이벤트가 실제 타겟 요소에 전달되는 단계
- 버블링 단계: 이벤트가 상위 요소로 전파되는 단계
아래 그림은 DOM트리에서 이벤트의 흐름을 그림으로 표현한 것입니다.
직접 그려보면서 이해하기
위 그림과 단계를 이해하고 문제를 다시 살펴보면 이렇습니다.
- element2를 클릭 합니다.
- 맨 상단의 조상인 window에서부터 이벤트가 시작되어 element2까지 전파됩니다.(캡쳐링 단계)
- element2에 할당된 이벤트를 처리합니다.(타깃 단계)
- 다시 window까지 이벤트가 전파됩니다.(버블링 단계)
- element1에 할당된 이벤트를 처리합니다.
- 이벤트 흐름이 종료됩니다.
캡쳐링
동일하게 element2를 클릭하면 element1이 먼저 출력되고 element2가 출력되게 하려면 어떻게 해야 할까요?
이때 캡쳐링을 이용하면 됩니다.
addEventListener의 options 이용해서 캡처링을 활성화 시켜주면 되는데요 기본적으로 addEventListener에서 기본값은 false(버블링)입니다.
target.addEventListener(type, listener, options);
ele1.addEventListener('click', () => {}, { capture: true });
다시 한번 그림을 보면서 문제를 살펴볼까요?
- element2를 클릭 합니다.
- 맨 상단의 조상인 window에서부터 이벤트가 시작되어 element2까지 전파됩니다.(캡쳐링 단계)
- 캡쳐링 단계에서 발견된 element1에 할당된 이벤트를 처리합니다.
- element2에 할당된 이벤트를 처리합니다.(타깃 단계)
- 다시 window까지 이벤트가 전파됩니다.(버블링 단계)
- 이벤트 흐름이 종료됩니다.
jsfiddle에서 확인 해주세요!
문제
이런식으로 이벤트핸들러를 등록 해놓으면 어떻게 될까요?
ele2.addEventListener('click', () => alert('버블:Element2'));
ele1.addEventListener('click', () => alert('버블:Element1'));
ele1.addEventListener('click', () => alert('캡쳐:Element1'), { capture: true });
- element2를 클릭 합니다.
- 맨 상단의 조상인 window에서부터 이벤트가 시작되어 element2까지 전파됩니다.(캡쳐링 단계)
- 캡쳐링 단계에서 발견된 element1에 할당된 이벤트를 처리합니다.
- element2에 할당된 이벤트를 처리합니다.(타깃 단계)
- 다시 window까지 이벤트가 전파됩니다.(버블링 단계)
- 버블링 단계에서 발견된 element1에 할당된 이벤트를 처리합니다.
- 이벤트 흐름이 종료됩니다.
캡쳐:Element1 -> 버블: Element2 -> 버블: Element1의 순서로 출력됩니다.
jsfiddle에서 확인 해주세요!
버블링과 캡쳐링의 역사
과거 넷스케이프 vs MS의 브라우저 전쟁이 있었다고 합니다. 맨 처음 언급한 문제에서
넷스케이프는 element1의 이벤트가 먼저 발생한다고 이야기했습니다.(캡처링)
마이크로소프트는 element2 이벤트가 우선한다고 했습니다.(버블링)
W3C에서는 현명하게 두가지를 모두 가질수 있는 중간을 선택하였고 현재의 이벤트 전달과 흐름을 가지게 되었다고 합니다.
can i use에서 capturing을 검색 해보면 IE 6-8은 캡쳐링 지원이 안된다고 확인이 되네요!
마치며
이벤트의 전달 단계와 흐름을 살펴보고 버블링, 캡쳐링을 간단하게 적용해보면서 알아봤는데요
실무예제 하나와 이벤트 위임에 대해서도 쓰려고 했으나 생각보다 글이 길어져서 2편에서 소개해드리겠습니다. 읽어주셔서 감사합니다!
댓글 기능이 광고 문제 때문에 아직 활성화가 되지 않았는데 해결 후 같이 의견 나눴으면 좋겠습니다.
참고문서