Event propagation-bubbling, capturing

Posted by yunki kim on June 23, 2021

<!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-부모 이벤트 부터 자식 이벤트.

  위 코드를 실행시키면 다음과 같은 결과가 나온다

capturing

  bubbling을 실행하기 위해서는 이벤트 리스너의 3번째 인자를 false 또는 없애면 된다

bubbling

*위 코드에서 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()을 사용하면 되는것을 알 수 있다.