[javascript] 이벤트 전파 (버블링/캡쳐링)
이벤트 전파
부모 - 자식의 계층 구조로 이루어진 각각의 요소(Element)에 이벤트를 부여할때 이벤트 발생순서를 정할 수 있습니다.
addEventListener()
ele.addEventListener('click', callback, false)
이벤트를 추가할때 사용한 addEventListener()는 3개의 인자를 전달합니다.
순서대로
- 이벤트 타입
- 콜백함수
- 이벤트 버블(false), 이벤트 캡쳐(true)
이벤트 타입은 click이냐, mousedown이냐, touchstart냐, keyup이냐 등의 이벤트 종류를 설정합니다.
콜백은 이벤트가 발생하면 실행할 함수입니다.
마지막에 true, false로 전달되는 이벤트 버블링/캡쳐링에 대하여 알아보겠습니다.
이벤트 버블링(Event Bubbling)
addEventListener의 세번째 인자는 boolean (true/false)으로 전달됩니다.
false는 버블링 (bubbling)
true는 캡쳐링 (capturing)
이라고 명칭합니다.
버블링 (bubbling)
버블링(false)는 자식노드부터 이벤트가 발생하여 부모로 이벤트가 전파됩니다.
<div class="a"><div class="b"><div class="c"></div></div></div>[스크립트]document.querySelector('.a').addEventListener('click', function(){console.log('a');}, false);document.querySelector('.b').addEventListener('click', function(){console.log('b');}, false);document.querySelector('.c').addEventListener('click', function(){console.log('c');}, false);
예제 코드처럼 a - b - c 의 순서의 계층 구조를 가지고 있는 구조에서 c를 클릭하면
가장 자식 노드인 c의 이벤트가 먼저 발생하고 부모인 b, a순서로 이벤트가 순차적으로 발생합니다.
캡쳐링 (capturing)
캡쳐링은 버블링과 반대로 부모노드에서 자식노드로 이벤트가 전파됩니다.
<div class="a"><div class="b"><div class="c"></div></div></div>[스크립트]document.querySelector('.a').addEventListener('click', function(){console.log('a');}, true);document.querySelector('.b').addEventListener('click', function(){console.log('b');}, true);document.querySelector('.c').addEventListener('click', function(){console.log('c');}, true);
캡쳐링(true)옵션을 주면 가장 부모인 a에서 자식인 b, c로 이벤트가 순차적으로 발생하게 됩니다.
이벤트 차단
다층 구조의 노드에 이벤트를 각 부여하였을때 특정 위치에서 이벤트를 차단해야 하는 경우가 종종 있습니다.
<div class="a"><div class="b"><div class="c"></div></div></div>[스크립트]document.querySelector('.a').addEventListener('click', function(){console.log('a');}, false);document.querySelector('.b').addEventListener('click', function(evt){evt.stopPropagation();console.log('b');}, false);document.querySelector('.c').addEventListener('click', function(){console.log('c');}, false);
위 예제는 이벤트 버블링 상황에서 b노드에서 이벤트를 차단한 예제입니다.
버블링 상태이기 때문에 가장 자식노드인 c부터 이벤트가 발생하고, 그 다음으로 b에 이벤트가 발생합니다.
그리고 b노드에서 콜백함수에서 전달 받은 event 아귀먼트의 stopPropagation() 메서드를 사용하면
b노드 이후의 이벤트 전파는 차단 됩니다.
<div class="a"><div class="b"><div class="c"></div></div></div>[스크립트]document.querySelector('.a').addEventListener('click', function(evt){evt.stopPropagation();console.log('a');}, true);document.querySelector('.b').addEventListener('click', function(){console.log('b');}, true);document.querySelector('.c').addEventListener('click', function(){console.log('c');}, true);
위 예제는 캡쳐링(true) 상황에서 가장 부모 노드인 a에서 이벤트를 차단했습니다.
그래서 그 이후의 b, c에서는 이벤트가 발생하지 않았습니다.
댓글