본문 바로가기

Javascript/Javascript

[Javascript] 이벤트 버블링

728x90
반응형

 
버블링(bubbling)의 원리는 간단하다.
 
한 요소에 이벤트가 발생하면 이 요소에 할당된 핸들러가 동작하고 이어서 부모 요소의 핸들러가 동작한다. 이러한 과정이 가장 최상단의 조상 요소를 만날 때까지 반복되면서 각 요소에 할당된 핸들러가 동작하는 것이다.
 

 
 
3개의 요소가 grand-div > parent-div > child-div 형태로 중첩된 구조.
가장 안쪽에 위치한 child-div를 클릭하면 다음과 같은 순서로 이벤트가 발생한다.
 
 
1) child-div에 할당된 onclick 핸들러가 동작한다.
2) parent-div에 할당된 onclick 핸들러가 동작한다.
3) grand-div에 할당된 onclick 핸들러가 동작한다.
4) 위와 같은 과정으로 document 객체를 만날 때까지 각 요소에 할당된 핸들러가 동작한다.
 
 
이러한 동작 방식 때문에 child-div를 클릭하면 child > parent > grand 순서로 3개의 console.log()가 출력된다.
 
 
이러한 흐름을 '이벤트 버블링'이라고 한다. 이벤트가 제일 깊은 곳에 있는 요소부터 시작해 부모 요소를 거슬러 올라가며 발생하는 모습이 물속 거품(bubble)과 닮았기 때문.
 

 
거의 모든 이벤트는 버블링된다.
여기서의 포인트는 '거의'. focus와 같이 버블링이 되지 않는 이벤트도 있으나 몇몇 이벤트를 제외한 대부분의 이벤트는 버블링된다.
 
 


 
 

버블링 중단하기: event.stopPropagation()

 
이벤트 버블링은 target 이벤트에서 시작해 <html> 요소를 거쳐 document 객체를 만날 때까지 각 노드에서 모두 발생하며
몇몇 이벤트는 window 객체까지 거슬러 올라가기도 한다.
 
그러나 핸들러에게 이벤트를 완전히 처리하고 난 후 버블링을 중단하도록 명령할 수도 있다.
 
아래 예시에서는 <button>을 클릭해도 <div>의 onclick은 동작하지 않는다.
 

 
 


 
 
 

event.stopPropagation()와 event.stopImmediatePropagation()

 
한 요소의 특정 이벤트를 처리하는 핸들러가 여러 개인 상황에서 핸들러 중 하나가 버블링을 멈추더라도 나머지 핸들러는 여전히 동작하게 된다.

event.stopPropagation()은 위쪽으로 일어나는 버블링은 막아 주지만 다른 핸들러들이 동작하는 건 막지 못하기 때문.
 

버블링을 멈추고 요소에 할당된 다른 핸들러의 동작도 막으려면 event.stopImmediatePropagation()을 사용하면 된다.
이는 요소에 할당된 특정 이벤트를 처리하는 핸들러 모두가 동작하지 않도록 한다.
 
 

 
 
 
위 예시에서 이벤트 전파를 막지 않고 child-div를 클릭하면 버블링에 따른 이벤트 전파가 발생한다.
 
이제 stopPropagation()와 stopImmediatePropagation()를 통해 이벤트 전파를 막고 둘의 차이를 확인해 보자.
 
 

stopPropagation()의 실행 결과

 
 
위의 예시에서 child-div를 클릭해 실행된 결과를 보면 상위 요소(parent, grand)로의 이벤트 전파는 막고 child에 할당한 이벤트 핸들러 2개는 모두 실행되었다.
 
 

stopImmediatePropagation()의 실행 결과

 
 
stopPropagation()을 사용했을 때와는 달리 'Hello child div'는 콘솔에 출력되지 않는다.
 
stopImmediatePropagation()은 상위로의 이벤트 전파뿐 아니라 같은 요소에 발생한 동일한 이벤트에 대한 다른 이벤트 핸들러의 실행까지 막는 것을 확인할 수 있다.
 
 
 
 
 

728x90
반응형