웹브라우저 JavaScript

이벤트 전파(버블링과 캡처링)

HTML 태그는 중첩되어 있다. 따라서 특정한 태그에서 발생하는 이벤트는 중첩되어 있는 태그들 모두가 대상이 될 수 있다. 이런 경우 중첩된 태그들에 이벤트가 등록 되어 있다면 어떻게 처리 될까? (실행)

<html>
    <head>
		<style>
			html{border:5px solid red;padding:30px;}
			body{border:5px solid green;padding:30px;}
			fieldset{border:5px solid blue;padding:30px;}
			input{border:5px solid black;padding:30px;}
		</style>
	</head>
	<body>
		<fieldset>
			<legend>event propagation</legend>
			<input type="button" id="target" value="target">			
		</fieldset>
		<script>
		function handler(event){
			var phases = ['capturing', 'target', 'bubbling']
			console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
		}
		document.getElementById('target').addEventListener('click', handler, true);
		document.querySelector('fieldset').addEventListener('click', handler, true);
		document.querySelector('body').addEventListener('click', handler, true);
		document.querySelector('html').addEventListener('click', handler, true);
		</script>
	</body>
</html>

실행결과

INPUT HTML capturing
INPUT BODY capturing
INPUT FIELDSET capturing
INPUT INPUT target

이벤트가 부모에서부터 발생해서 자식으로 전파되고 있다. 이러한 방식을 capturing이라고 한다. ie 낮은 버전에서는 작동하지 않기 때문에 많이 사용하지는 않는다.

코드를 아래와 같이 변경해보자. (실행)

document.getElementById('target').addEventListener('click', handler, false);
document.querySelector('fieldset').addEventListener('click', handler, false);
document.querySelector('body').addEventListener('click', handler, false);
document.querySelector('html').addEventListener('click', handler, false);

차이점은 addEventListener의 3번째 인자가 false로 변경 되었다.

실행결과

INPUT INPUT target
INPUT FIELDSET bubbling
INPUT BODY bubbling
INPUT HTML bubbling 

이번에는 순서가 반대로 되었다. 자식부터 부모로 이벤트가 전파되는 것을 버블링(bubbling)이라고 한다.

이벤트 전파를 중간에 가로막을 수도 있다.

아래처럼 코드를 변경해보자. (실행)

function handler(event){
	var phases = ['capturing', 'target', 'bubbling']
	console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
}
function stophandler(event){
	var phases = ['capturing', 'target', 'bubbling']
	console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
	event.stopPropagation();
}
document.getElementById('target').addEventListener('click', handler, false);
document.querySelector('fieldset').addEventListener('click', handler, false);
document.querySelector('body').addEventListener('click', stophandler, false);
document.querySelector('html').addEventListener('click', handler, false);

실행결과

INPUT INPUT target
INPUT FIELDSET bubbling
INPUT BODY bubbling
참고로 ie9 이전의 브라우저에서는 이벤트 전파을 막기 위해서 event.cancelBubble 프로퍼티를 사용해야 한다.

댓글

댓글 본문
작성자
비밀번호
  1. tachyon
    감사합니다
  2. 우욱진
    감사합니다.
  3. JustStudy
    2016.07,13 수
    고맙습니다 3.
  4. JustStudy
    2016.07.02 토
    고맙습니다 2.
  5. 온달장군
    강좌 잘보고 갑니다. 감사합니다.
  6. Halora
    다른 분 말씀대로 Event가 호출된 Element가 복수일 상황의 실질적인 예시가 궁금하여요!

    Event 인터페이스 eventPhrase 상수 정리입니다.
    https://developer.mozilla.org......ase

    Event.CAPTURING_PHASE(캡쳐링) 1
    Event.AT_TARGET(타겟) 2
    Event.BUBBLING_PHASE(버블링) 3


    괜한 실험정신으로 해보았을 때, 캡쳐링과 버블링이 섞여 있을 때에는 캡쳐링이 우선하네요. :)
  7. 이주환
    2016. 04. 28
    잘보고 갑니다~!
    확인결과 event.eventPhases 값은
    Capturing -> 1
    bubbling -> 3
    이네요.
  8. JustStudy
    고맙습니다
  9. 박찬울
    JavaScript 문서상에서 이벤트가 놓여진 순서에 관계 없이 노드들의 자식-부모 관계에 따라 이벤트가 처리된다고 이해하면 맞는걸까요?

    또한, 버블링과 캡쳐링이 각각 어느 상황에서 쓰이는지 실용적인 예를 한가지씩만 알기 쉽게 설명해주시면 감사하겠습니다.
  10. Peater Han
    2번째 영상에서 addEventListener를 거꾸로 도식과 연결하셔서 이상하게 생각했었는데, 댓글보고 실수하신거 알았네요. 다음 버전을 추가로 촬영하실때 수정해주시겠죠 ㅎㅎ 잘봤습니다.
  11. WayneKing
    버블링과 캡처링을 통해서 전파가 되는 방향을 알겠는 데.
    전파되는 방향에 따라 뭐가 다르게 움직이는 지, 알 수있는 소스가 있으면 좋겠네요.

    그리고 중복된 영역안에서 같은 이벤트를 추가하는 일이 많은가요?
  12. 코딩!
    감사합니다
  13. Soon Chul Jang
    짝짓기 반대로 된게 맞아요
    대화보기
    • 찐똥구리구리
      제가 이해하는 바는 캡쳐링은 이벤트를 작동시키는 순서와 상관없이 이벤트 핸들러가 위치한 부모, 자식관계를 따져 부모 먼저, 요렇게 생각이 드는 대요. 제가 캡쳐링 예제에서 4줄의 이벤트 리스너호출 순서를 뒤바꿔 작동 시켜도 똑같은 결과가 나왔네요. 그렇게 치면 동영상 두번째 동영상 8:40의 짝짓기는 반대로 된거 아닌가요?? 제가 이해를 여전히 못하고 있는 것인가요?? 도와주세요~~ 어렵네요.
    • 히히
      세번재 인자값을 생략하면 default값이 false로 되는것으로알고있어요
    • 창가
      재미있네요!~
    • T-BONE Steak
      addEventListener() 의 세번째 인자값을 생략하니까, bubbling이 되네요.

      그럼 bubbling을 사용할때 리스너의 세번째 인자값을 선언 안해도 문제가 없는걸까요?
    • 수험생
      대화보기
      • 상상초월
        3번째 동영상 6분 13초 정도 이후에 나오는 설명중 궁금한 것이 있습니다.
        마지막 자식(말단) 태그에서 호출된 '이벤트 헨들러'에는 eventPhase 프로퍼티가 1이 담긴다고 하셨는데.
        실습 해보니 2인거 같습니다.
        캡처링 방식으로 호출된 핸들러는 1, 말단은 2, 버블링은 3 이렇게 정리하면 맞을까요?
      • somdari
        이벤트 전파에 대한 멋진 강의 감사합니다.. 어려운 주제가 될 수 있는것도 먹기좋게 보기좋게 요리 잘해서 제공해주시네요..^^;
      버전 관리
      egoing
      현재 버전
      선택 버전
      graphittie 자세히 보기