이벤트의 발생
웹상에서 사용자에 의해 어떠한 행동(이벤트)이 발생하면 다음의 두가지 경우로 해당 이벤트의 전달이 이루어진다.
이벤트 Bubbling
기본적으로 이벤트는 버블링 옵션으로 발생한다.
버블링은 html의 노드계층에 있어서 특정 계층에서 이벤트의 발생이 이루어지면 해당 계층부터 상위 계층으로 순차적으로 해당 이벤트의 전달이 이루어진다.
1 | <style> |
2 | .root{ |
3 | height:100px; |
4 | width:100px; |
5 | border: 1px solid black; |
6 | } |
7 | .center{ |
8 | height:80px; |
9 | width:80px; |
10 | border: 1px solid black; |
11 | } |
12 | .bottom{ |
13 | height:60px; |
14 | width:60px; |
15 | border: 1px solid black; |
16 | } |
17 | </style> |
18 | <body> |
19 | <div class="root"> |
20 | <div class="center"> |
21 | <div class="bottom"></div> |
22 | </div> |
23 | </div> |
24 | </body> |
25 | <script> |
26 | const divs = document.querySelectorAll('div'); |
27 | divs.forEach(function(div){ |
28 | div.addEventListener('click', eventLog); |
29 | }); |
30 | |
31 | function eventLog(e){ |
32 | console.log(e.currentTarget.className); |
33 | } |
34 | </script> |
위의 코드를 실행하여 제일 안쪽의 상자를 클릭하면 콘솔에 다음과 전달되어 순서대로 출력된다.
반대로 제일 바깥쪽 상자를 클릭하면 콘솔에 root 하나만 출력된다.
이벤트 Capture
이벤트 캡쳐는 버블링과는 반대로 특정 노드계층에서 이벤트의 발생이 이루어지면 body 계층부터 하위 계층으로 순차적으로 해당 이벤트의 발생지점까지 탐색과 전달이 이루어지는 현상이다.
캡쳐 옵션은 이벤트 리스너를 메서드에 세번째 인자로 true를 넣어주면 발생한다.
1 | const divs = document.querySelectorAll('div'); |
2 | divs.forEach(function(div){ |
3 | div.addEventListener('click', eventLog, true); |
4 | }); |
5 | |
6 | function eventLog(e){ |
7 | console.log(e.currentTarget.className); |
8 | } |
버블링과 캡쳐를 이용하면 이벤트리스너 설정에 있어 성능적으로 유용한 작업을 할 수 있다.
이벤트의 제어
이벤트가 짧은 시간에 의도치않게 수없이 많이 실행될 경우 브라우저가 성능적으로 안좋아질 수 있다.
예를들어 마우르 스크롤 이벤트가 부여된 상태에서 스크롤 막대를 드래깅한다고 생각해보자.
무수한 이벤트 비용이 발생하여 콜스택 지연현상으로 브라우저가 동작하지 않을 수 있다.
이러한 문제를 제어하기 위해 두가지 기법이 존재하는데 다음과 같다.
디바운싱(Debouncing)
디바운싱은 연이어 호출되는 함수들 중 마지막 함수(또는 첫 함수)만 호출하도록 하는 기법이다.
1 | let timer |
2 | document.querySelector('input').addEventListener('input', function (e) { |
3 | if (timer) { |
4 | clearTimeout(timer); |
5 | } |
6 | timer = setTimeout(function () { |
7 | console.log(e.target.value); |
8 | }, 500); |
9 | }); |
쓰로틀링(Throttling)
쓰로틀링은 이벤트를 일정한 주기마다 발생하도록 하는 기법이다.
1 | let timer; |
2 | window.addEventListener('scroll', function () { |
3 | if (!timer) { |
4 | timer = setTimeout(function () { |
5 | timer = null; |
6 | console.log("1000ms주기로 실행"); |
7 | }, 1000); |
8 | } |
9 | }); |
버블링과 캡쳐링 제어
1 | event.stopPropagation() |
를 추가해준다.![]()

