빼먹거나 놓친 것들. 2. 이벤트 버블링과 캡쳐링

Sal Jeong·2022년 8월 11일
1
post-thumbnail

항상 실무형 개발자라고 내 자신을 소개해 왔었다.
하지만 최근 면접을 보면서 내가 실제로 경험했고, 해결한 문제라고 하더라도 해당 문제가 어떤 이론적 배경을 가지고 있는지 설명을 제대로 할 수 없었다. 잘 모르니까 그런 것이다. 이 버블링 역시 마찬가지다.(캡쳐링은 처음 들었지만)

https://ko.javascript.info/event-delegation

모던 Javascript 튜토리얼이라는 ebook 번역 사이트에서 아주 설명이 잘 되있었다.
번역해주신 여러분들께 감사 드립니다.

1. 이벤트 버블링

위 사이트에 따르면, 버블링이란

한 요소에 이벤트가 발생할 시, 요소의 핸들러가 동작하고 부모 요소의 핸들러가 함께 동작하는 것. 그 부모의 부모에도 핸들러가 있다면 따라 올라가면서 같이 실행된다.

몇몇 이벤트를 제외하고, 이 동작은 항상 일어난다.

2. 이벤트 타겟, this

또한, 해당 이벤트에 대해서 event.target, event.currentTarget 두 가지의 컨텍스트를 바라볼 수 있다.

  1. event.target은 실제 이벤트가 시작된 타겟. 이벤트가 시작된 요소를 바라봄
  2. this(event.currentTarget)는 현재 실행 중인 핸들러가 할당된 요소.

https://codepen.io/jihyeonjeong11/pen/NWYBEGm

이해를 돕기위한 코드펜

js에서 모든 element에 이벤트를 걸어 주었다.

  alert('current ' + event.target.id + ', this ' + event.currentTarget.id)

위처럼 event.target과 this를 출력하게끔 해 놓았는데, 이 경우

nested된 마지막 button을 클릭할 경우,
event.target은 inner에서 바뀌지 않음. this는 inner부터 시작해서 버블링으로 상위 이벤트가 순서대로 실행되므로 outer 3~1까지 실행될 것이다.



생각했던 대로 잘 실행이 된다.

3. 버블링 중단

  // event.stopPropagation()

그리고 해당 메소드를 호출해 위 버블링을 막을 수 있다.

다만 이런 액션은 권장하지 않는데,

버블링을 막아버릴 경우, 유저 행동 데이터를 수집하기 위해 요소마다 click 이벤트를 달아 놓고 stopPropagation해버릴 경우, 요소별로 클릭되었다는 것을 수집하기 위한 버블링이 막혀버리기 때문이다.
이 부분은

let event = new Event(type[, options]);

와 같은 방식으로 커스텀 이벤트를 선언하며, options 인자에 bubbles : false를 넣어줌으로써 stopPropagation을 쓰지 않고 사용할 수 있다.

4. 캡쳐링

표준 DOM 이벤트에서 정의한 이벤트 흐름엔 3가지 단계가 있다고 한다.

캡처링 단계 – 이벤트가 하위 요소로 전파되는 단계
타깃 단계 – 이벤트가 실제 타깃 요소에 전달되는 단계
버블링 단계 – 이벤트가 상위 요소로 전파되는 단계

따라서, 사실 이벤트 실행 -> 버블링 이전에는 캡처링이라는 단계가 또 있는 것.

위의 코드펜 코드에서, 리스너 부분을 true로 바꾸어 주면 위의 이벤트리스너는 캡쳐링 과정에서만 실행된다고 한다.

그렇다면 버블링 순서와는 반대로, 맨 위 엘리먼트에서 맨 아래로 내려올 것이고,
이 경우, 맨 하단의 버튼을 클릭할 시 event.target은 inner, this는 outer1~inner로 반대로 작동할 것이다.

e.addEventListener("click", clickEvent, true)


생각했던 대로 잘 실행된다.

profile
Can an old dog learn new tricks?

0개의 댓글