이벤트 버블링과 이벤트 캡처
HTML태그는 태그들이 중첩되어있는 구조이다. <html>의 child로 <body>가 있고 <body>의 child에 <div>가 있고 <div>의 child로 <button>.... 가 반복된다. 이러한 태그의 중첩구조에서 하나의 태그에서 이벤트가 발생했을 때 해당 이벤트가 child로 혹은 parent로 전파되는 현상이 이벤트 버블링과 이벤트 캡쳐이다.
1. 이벤트 버블링
See the Pen Bubbling by ImHyeLim1209 (@imhyelim1209) on CodePen.
위의 코드는 container > content > inner 로 div가 중첩되어있으며 각 div를 클릭 시 각자의 id가 alert되는 이벤트가 걸려있다. 이 때 사용자가 inner를 클릭하면 이벤트가 inner의 parent인 content, content의 container로 전파되어 inner, content, container 순으로 모두 click 이벤트가 발생한다. 즉 하위노드에서 상위노드로 이벤트가 전파되는 현상이다. focus 등 일부 이벤트를 제외한 거의 모든이벤트가 이벤트 버블링이 발생한다.
2. 이벤트 캡쳐
See the Pen capture by ImHyeLim1209 (@imhyelim1209) on CodePen.
이벤트 캡쳐링은 이벤트 버블링과 반대로 상위노드에서 하위노드로 이벤트가 전파되는 현상이다. 위의 코드에서 inner를 클릭했을 때 이벤트 버블링 코드 때와는 달리 클릭 이벤트가 container, content, inner 순으로 발생하는 것을 볼 수 있다(alert 창이 container, content, inner 순으로 팝업된다). addEventListenr의 마지막 파라미터에서 이벤트 캡쳐링을 지정할 수 있으며, boolean 값으로 true를 넣어도 되고, 객체로 { capture: true }를 넣어도 된다.
3. 이벤트 전파 방지
See the Pen propagation by ImHyeLim1209 (@imhyelim1209) on CodePen.
이벤트 버블링, 이벤트 캡쳐링과 같은 이벤트 전파를 방지하기 위해선 event.stopPropagation()을 사용하면 된다. 이벤트 콜백함수에서 이벤트객체.stopPropagation()을 호출하면 이벤트는 더 이상 전파되지 않는다. 위의 코드에서 inner를 클릭하면 e.stopPropagation() 때문에 Content, Container로 이벤트가 전파되지 않는 것을 볼 수 있다.
4. 이벤트 위임
See the Pen EventDelegation by ImHyeLim1209 (@imhyelim1209) on CodePen.
이벤트 전달은 이벤트 위임 패턴으로 활용될 수 있다. 위와 같이 ul 태그 안에 li가 있고 li를 선택하면 해당 li의 textContent를 alert창으로 팝업시키는 기능을 구현해보자. 이벤트 위임을 모른다면 li태그에 일일히 click 이벤트를 추가해주어야할 것이다. 이벤트 위임을 안다면 이벤트가 하위노드에서 상위노드로 버블링 된다는 사실을 알기 때문에 상위 노드인 하나의 ul태그에 click 이벤트를 추가하여 구현할 수 있다. li를 클릭하면 ul도 click 이벤트가 발생하며 이벤트 객체의 target 속성(e.target)을 이용하여 어떤 요소가 클릭되었는지 알아낼 수 있기 때문이다.
참고 사이트