Pandaman Blog

[JS] Javascript의 Event 본문

Front end/Javascript

[JS] Javascript의 Event

oyg0420 2020. 2. 28. 21:55

Event란

이벤트란 어떠한 사건을 의미한다. 브라우저에서의 이벤트는 예를 들어 사용자가 버튼을 클릭했을 때 스크롤했을 때 등등 다양한 이벤트가 존재한다. 브라우저가 이벤트를 감지하고, 그에 대응하는 처리를 호출해주는 방식에 대해서는 지난 포스팅인 이벤트 루프에서 학습했다. 이번 시간에는 요소에서 발생한 이벤트를 어떠한 방식으로 다른 화면 요소에 전파하는지 알아보자.

DOM Event의 전파 방식

계층적 구조에 포함되어 있는 HTML 요소에 이벤트가 발생할 경우 연쇄적 반응이 일어난다.
한마디로 이벤트 전파가 되는데 전파 방향에 따라 버블링(Bubbling)과 캡쳐링(Capture)으로 나눌 수 있다.
addEventListener메소드의 세 번째 매개변수에 true를 설정하면 캡쳐링으로 전파되는 이벤트를 캐치하고, false로 설정하면 버블링으로 전파되는 이벤트를 캐치한다. 기본값은 false이다.

Event Bubbling

이벤트 버블링은 자식 요소에서 발생한 이벤트가 부모 요소로 전파되는 것을 말한다.
예제를 통해 알아보자.

first요소는 second요소를 감싸고 있고, second 요소는 third 요소를 감싸고 있다.
우리는 버블링으로 전파되는 이벤트를 캐치하기 위해 addEventListener메소드의 3번째 인수(useCature)에 false를 할당했다.
click 이벤트가 발생하고 Web APIs에 전달될 콜백 함수는 eventHandler로 현재 이벤트가 전달된 요소의 클래스 이름을 로그를 통해 나타낸다.
코드에 대한 설명은 끝났으니 이제 테스트를 시작해보자. 결과는 third -> second -> first 순으로 로그가 남는 것을 확인할 수 있다. third요소를 클릭하면 click 이벤트가 발생하고 third 요소의 이벤트 핸들러가 동작하고, 이벤트는 second 요소로 전파되어 이벤트 핸들러가 동작한다. 마지막으로 이벤트가 first 요소로 전파되면서 동일한 동작을 한다.

Event Capturing

이벤트 캡쳐링은 자식 요소에서 발생한 이벤트가 부모 요소부터 시작하여 이벤트를 발생시킨 자식 요소까지 도달하는 것을 말한다.
우리는 캡쳐링 이벤트 전파를 확인해야 하므로 이전 예제에서 addEventListener메소드의 3번째 인수(useCature)에 true로만 변경했고, 다른 코드는 변경사항이 없다.

third 요소를 클릭해보자. 결과는 first -> second -> third 순으로 로그가 남는 것을 확인할 수 있다. third 요소에서 click 이벤트가 발생하면 third 요소를 감싸고 있는 가장 상위의 요소인 first요소에 이벤트가 전파되고 이벤트 핸들러가 동작한다. 그리고 바로 하위 요소인 second 요소로 이벤트가 전파되며 이벤트 핸들러가 동작한다. 마지막으로 이벤트를 발생시킨 third 요소로 이벤트가 도달하고, 이벤트 핸들러가 동작하여 결과와 같이 로그가 남는 것을 확인할 수 있다.

이렇게 버블링과 캡쳐링에 대해 학습했다. 주의할 점은 버블링과 캡쳐링은 둘 중 하나만 발생하는 것이 아니라 캡쳐링부터 시작하여 버블링으로 종료한다는 것이다. 즉, 이벤트가 발생했을 때 캡쳐링과 버블링은 순차적으로 발생한다.

캡쳐링과 버블링이 혼용된 예제를 살펴보자.

second요소는 캡쳐링 이벤트 흐름만 감지하게 설정했으며, first, third요소는 버블링 이벤트 흐름만 감지하게 설정했다.
third요소를 클릭하면 로그는 어떻게 남을까? 결과는 second -> third -> first 순으로 로그가 남는다.
third요소를 클릭하면 캡쳐링이 발생하므로 캡쳐링 이벤트 흐름만 감지하게 설정된 second 요소의 이벤트 핸들러가 동작한다. 이벤트를 발생시킨 third 요소에 이벤트가 전파되고 버블링이 시작되면 버블링 이벤트 흐름만 감지하게 설정된 third 요소의 이벤트 핸들러가 동작한다. 마지막으로 이벤트가 first 요소에 전파되면 first 요소의 이벤트 핸들러가 동작한다. 따라서 위와 같은 결과를 얻을 수 있다.

이벤트 위임(Delegation)

일단 아래의 예제를 살펴보자.

위 예제는 각각의 liclick이벤트가 발생했을 때 반응하는 처리를 구현한 것이다. 현재는 총 5개의 li요소에 대해서 이벤트 핸들러를 바인딩해주었지만, 만약 li요소가 100개, 1000개라면? 우리는 100개, 1000개의 요소에 일일이 이벤트 핸들러를 바인딩해주어야 할까?

우리는 이러한 경우 이벤트 위임(Delegation)을 사용한다. 이벤트 위임이란 다수의 자식 요소에 각각의 이벤트 핸들러를 바인딩하는 대신 자식 요소들이 속한 하나의 부모 요소에 이벤트 핸들러는 바인딩하는 방법이다.
이벤트 위임이 가능한 이유는 위에서 학습한 이벤트의 버블링 덕분이다. 한마디로 자식 요소에서 발생한 이벤트가 부모 요소에도 전파되기 때문이다.

따라서 우리는 위의 예제를 아래와 같이 변경할 수 있다.

li의 부모 요소인 ul에 이벤트 위임을 해주었다. 이것으로 ul의 자식 요소들인 각각의 liclick 이벤트가 발생하면 부모 요소인 ul에 이벤트가 전파되어 ul요소의 이벤트 핸들러가 작동해 Target에 따른 반응을 처리할 수 있게 되었다.

 

 

 

 

참고: https://poiemaweb.com/js-event


파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음
Comments