해당 포스팅은 생활코딩의 이고잉 님의 강의를 기반으로 개인 공부용으로 정리한 포스팅임을 미리 알립니다.
자바스크립트 기본 문법 : 이벤트 전파 - 캡처링(Capturing)
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>
위의 예제 코드에서, 제일 안쪽에 존재하는 id 가 target 인 버튼을 눌러보도록 하겠습니다.
이벤트가 부모에서부터 발생해서 자식으로 전파되고 있는 것을 확인할 수 있습니다.
이러한 방식을 capturing이라고 합니다.
ie 낮은 버전에서는 작동하지 않기 때문에 많이 사용하지는 않습니다.
자바스크립트 기본 문법 : 이벤트 전파 - 버블링(Bubbling)
이번에는 코드를 아래와 같이 변경해보도록 하죠.
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 의 세번째 인자가 false 로 변경되었습니다.
이 코드로 수정해서 실행하면, 아래 그림과 같은 결과가 출력됩니다.
캡처링의 케이스와 달리 순서가 반대로 된 것을 알 수 있습니다.
이렇게 자식부터 부모로 이벤트가 전파되는 것을 버블링(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);
다음과 같이 HTML 까지 이벤트 전파가 되지 않은것을 확인할 수 있습니다.
이처럼 이벤트 전파를 막기위해서는 일반적으로 event.stopPropagation() 을 사용합니다.
하지만 ie9 이전의 브라우저에서는 이벤트 전파를 막기 위해서
event.cancelBubble 프로퍼티를 사용해야합니다.