웹브라우저 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. 헤밍웨이
    220825 감사합니다~
  2. 임앤강
    2022-02-14 감사합니다.
  3. tekhnolozy
    생활코딩 예시가 맥락에서 좀 안 맞는 부분이 있습니다.
    조금 더 적절한 에시가 있는 링크에 가셔서 학습하세요 !

    https://joshua1988.github.io......on/
  4. 드림보이
    2021.12.31. 이벤트 전파 (버블링과 캡처링) 파트 수강완료
  5. pmxsg
    2021.12.23. 수강
  6. labis98
    20210912 좋은 강의 감사합니다.
  7. 세번째 영상 5:45 참고
    Event.eventPhase - MDN Web Docs
    https://developer.mozilla.org......ase
  8. 함께 작동시켜야하는 이벤트들을 줄세우는 방법 addEventListener('이벤트명', 함수, true: 캡쳐링(부모객체->자식객체순) false: 버블링(자식객체->부모객체순서))
    event.stopPropagation() = 다음 캡처링이나 버블링을 멈춤
  9. 박병진
    2020.12.10 완료
  10. 싸알
    완료
  11. anne
    완료
  12. 한강
    이밴트 전파라는게 있군요. ㅎㅎ
    오늘도 감사합니다~~^^!
    200710
  13. Gritter
    실제로 캡쳐링, 버블링 기능이 어떻게 사용되는지 실용적인 예시가 있으면
    이해에 도움이 될 것 같아요. 감사합니다.
  14. 굼벵이
    완료
  15. 우엥
    html에서 element들은 다른element의 자식이거나 부모인데.
    각각이 클릭이벤트가 있을시에
    자식을 클릭했을때 부모도 클릭한것이고 그 부모의 부모도 클릭한것이기때문에
    누가 먼저 실행 될지를 설정하기위해 이벤트흐름을 만든거아닙니까.
  16. JuicyFresh
    감사합니다.

    event.target.nodeName : 실제 이벤트가 일어난 node의 name.
    this.nodeName : addEventListner가 등록된 node의 name. / event 발생의 max 범위.
    event.stopPropagation() : 버블링, 캡쳐링 중단.
  17. 김수
    20180901 감사용
  18. 피자
    ㅋㅋ 그런것같음 저도 이상하다 해서 댓글봤는데, 이고잉선생님이 틀리게 설명하신 것 같음
    대화보기
    • 제갈량
      이번 강의는 HTML의 계층구조를 안다면 쉬운 문제네요.
    • akxltmzk@gmail.com
      두번째 동영상에서 9분 30초 부분의 화살표로 설명해주시는 부분은 반대가 아닌가요 ..이해가 잘안되서요!
    • 박인호
      12-31
      수강완료.
    • Byungsoo Kim
      감사합니다.<<<
    • crable
      감사합니다.
    • Keehwan Jee
      @이철규 저도 왜 어디에 사용되는지 아직 감이 오질않는군요.
    • 신입1
      감사합니다.
    • 이철규
      '도대체 왜? 어디에?' 사용되는지는 아직 와닿지가 않네요 ㅠㅠ
    • 바람을 느껴봐
      이벤트 전파는 Sync로 동작하나요? 위 예제에서 버블링으로 target을 클릭했을 때 target 이벤트 핸들러 함수가 '종료'되고 filedset 으로 이어지는지 궁금합니다~
    • tachyon
      감사합니다
    • 우욱진
      감사합니다.
    • JustStudy
      2016.07,13 수
      고맙습니다 3.
    • JustStudy
      2016.07.02 토
      고맙습니다 2.
    • 온달장군
      강좌 잘보고 갑니다. 감사합니다.
    • Halora
      다른 분 말씀대로 Event가 호출된 Element가 복수일 상황의 실질적인 예시가 궁금하여요!

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

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


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

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

      그리고 중복된 영역안에서 같은 이벤트를 추가하는 일이 많은가요?
    • 코딩!
      감사합니다
    • 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 자세히 보기