상세 컨텐츠

본문 제목

브라우저: 이벤트 버블링, 캡쳐링, 그리고 위임

자바스크립트

by lazz 2021. 9. 13. 02:59

본문

반응형

이벤트 버블링

이벤트 버블링이란 어떤 element에서 이벤트가 발생했을 때, 해당 element의 event handler를 실행한 다음, 부모 element부터 루트 element에 도달할때까지의 event handler가 실행되는 원리를 뜻한다.


확인을 위해 html 모든 태그에 currentTarget을 출력하는 이벤트를 붙여보자.

`event.target` 은 실제 이벤트가 시작된 element이다. 

`this`와 `event.currentTarget` 은 현재 핸들러를 실행중인 element이다.

실행 결과 버튼이 위치한 4번 부터 1번까지, 그리고 body와 html 태그의 event handler를 순차적으로 실행시키는 모습을 확인할 수 있다.

만약 event.currentTarget을 event.target으로 변경하면 이렇게 버튼 element가 계속 출력된다.



주의

거의 모든 이벤트가 버블링 되지만, 모든 이벤트가 버블링 되는 것은 아니다.

예시에서 click 이벤트는 document 까지 올라갔지만, 어떤 이벤트는 window까지 버블링 되기도 한다.



버블링 막기

경우에 따라 버블링을 막아야 할 수도 있다. 그럴땐 event.stopPropagation() 메소드를 사용하면 된다.


예시에서 버튼 이벤트에 stopPropagation 메소드를 호출하면 부모 노드로 버블링 되는 것이 멈춘다.



이벤트 캡쳐링

이벤트 캡쳐링은 이벤트 버블링과 반대로 위에서 target 요소에 도착할 때 까지 전파되는 단계를 의미한다.

DOM 이벤트에서 정의한 이벤트 흐름은 3가지 단계로 나뉜다.

  1. 캡쳐링 - 이벤트가 하위 요소로 전파됨
  2. 타겟 - 이벤트가 실제 타겟 요소에 전달됨
  3. 버블링 - 이벤트가 상위 요소로 전파됨

캡쳐링 단계에서 이벤트를 확인하려면 addEventListenercapture옵션을 true로 설정하면 된다.


버블링과 반대로 위에서 아래로 내려가면서 출력된다.



이벤트 캡쳐링을 사용하는 경우는 거의 없다고 한다.



이벤트 위임

이벤트 위임은 캡쳐링과 버블링을 이용한 이벤트 핸들링 패턴이다. 주로 비슷한 방식으로 여러 element를 다뤄야 할 때 element 마다 event handler를 등록하는 대신 element의 공통 부모에 핸들러를 등록하는 식이다.

세개의 버튼이 있고, 각 버튼에 event handler를 등록해야 한다고 가정해보자.

나이브하게 접근하면 각 버튼 element를 찾아 핸들러를 등록하는 방식을 떠올릴 수 있다.

하지만 버튼이 3개가 아니라 100개라면? 100번의 querySelector와 addEventListener를 호출해야 한다.

이벤트 위임을 이용하면 이런 문제를 우아하게 해결할 수 있다.

버튼의 부모인 메뉴 element에 하나의 event handler를 등록하고, 핸들러가 data-action 값을 이름으로 하는 함수를 호출하도록 만들면 된다.

전과 비교하면 훨씬 깔끔하고 확장성도 있다.



확장성

이벤트 위임을 이용해 아래와 같은 문제도 해결할 수 있다.


버튼 태그를 모두 찾아 클릭시 data-action 값을 출력하는 핸들러를 등록했다.

이 경우, 두개의 버튼이 의도한대로 동작한다.

이 상태에서 동적으로 검색하기 버튼을 추가하는 상황을 가정하자.


실행해보면 검색하기 버튼은 생겼지만 눌러도 값이 출력되지 않는다. 이벤트를 등록하는 시점이 버튼을 새로 만드는 시점보다 빠르기 때문에 생기는 현상이다.

이런 상황에서 동적으로 버튼을 추가할 때 마다 이벤트를 등록해주기 보다, 이벤트 위임을 활용해보자.

메뉴 element에 핸들러를 등록하고 event.target의 data-action값을 출력하도록 했다.

이벤트 등록 후에 버튼을 생성해도 의도한대로 동작한다!



마무리

이벤트 위임은 강력한 패턴인 것 같다. 최상단 document 자체에 공용으로 사용되는 이벤트를 등록해서 사용하는 것도 가능하다.

이벤트 위임을 활용하지 않더라도, 이벤트 흐름을 이해하는 것도 큰 도움이 될 것 같다.

생각보다 재미있다.



출처

https://ko.javascript.info/bubbling-and-capturing
https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/#이벤트-버블링---event-bubbling

반응형

관련글 더보기

댓글 영역