<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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>
<title>Title</title>
</head>
<body>
<fieldset>
<legend>event propagation</legend>
<input type="button" id="target" value="target">
</fieldset>
<script>
function handler(event) {
const 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>
위와 같은 코드가 있다고 하자. 태그는 부모, 자식 관계를 가진다. 이때 html, body, fieldset, input태그에 각각 이벤트를 장착했다고 하자. 그 후 버튼을 클릭했을때 html은 body를 감싸고 있고, body는 filedset을, filedset은 input을 감싸고 있기 때문에 어떤 순서고 이벤트가 발생할 것인가를 event propagation이라 한다.
event propagation은 두 종류가 있다. (1). bubbling-자식 이벤트 부터 부모 이벤트, (2). capturing-부모 이벤트 부터 자식 이벤트.
위 코드를 실행시키면 다음과 같은 결과가 나온다
bubbling을 실행하기 위해서는 이벤트 리스너의 3번째 인자를 false 또는 없애면 된다
*위 코드에서 event.eventPhase는
1. capturing일때는 1
2. 가장 아래의 이벤트 일때는 2
3. bubbling일때는 3
을 반환한다.
stopPropagation()
위 코드에 다음과 같은 함수 하나를 추가하자
function stopHandler(event){
const phases = ['capturing', 'target', 'bubbling'];
console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase - 1]);
event.stopPropagation();
}
그 후 body tag의 콜백을 stopHandler로 바꾸자. 그러면 다음과 같은 결과가 나온다
따라서 이벤트 전파를 멈추기 위해서는 stopPropagation()을 사용하면 되는것을 알 수 있다.