-
자바스크립트 - 이벤트 버블링과 캡쳐링프론트엔드/JavaScript 2020. 10. 20. 10:37
자바스크립트에서 이벤트를 실행하면 버블링과 캡쳐링이란 것을 발생하게 할 수 있다.
간단하게 말하자면 이벤트가 발생 시 HTML 문서 구조상 이벤트가 다른 문서로 전이되는 것을 말한다.
코드를 살펴보자.
1. 캡쳐링과 버블링
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body id="body"> <div id="div"> <p id="p"> <button id="btn"> 캡쳐링과 버블링 </button> </p> </div> </body> <script> let button = document.getElementById("btn"); let p = document.getElementById('p'); let div = document.getElementById('div'); let body = document.getElementById('body'); function ftest(){ console.log("일어난 이벤트: "+event.target.nodeName+" 이벤트가 일어나는 현재 노드: "+this.nodeName); } btn.addEventListener('click', ftest, true); p.addEventListener('click', ftest, true); div.addEventListener('click', ftest, true); body.addEventListener('click', ftest, true); </script> </html>
위 코드를 살펴보자.
대략 그림으로 위 HTML문서의 구조를 나타내면 다음과 같다.
이때 여기서 버튼을 누르면 어떤 결과가 나올까?
다음과 같은 결과가 나온다.
버튼은 한번만 눌렀는데 결과값은 4개가 나온 것이다.
HTML 문서의 각 노드들은 어딘가 종속되어있는 계층적 구조로 이뤄진다.
그래서 어느 한 곳에서 이벤트가 발생하면 다른 곳으로 이벤트가 전파된다.
그리고 이때 이 이벤트가 전파되는 방향에 따라 이것을 캡쳐링과 버블링이라고 부르는 것이다.
둘은 구분하면 다음과 같다.
캡쳐링: 자식 요소에서 발생한 이벤트가 부모 요소에서 시작해 이벤트가 발생한 자식 요소까지 도달하는 것
버블링: 자식 요소에서 발생한 이벤트가 부모 요소로 전파되는 것
그림으로 나타내면 다음과 같다.
위 코드는 캡쳐링을 나타내는 코드로서 실행 결과는 다음과 같다.
캡쳐링은 아래와 같이 <body> - <div> - <p> - <button> 순으로 이벤트가 실행된다.
버블링 코드는 아래와 같다.
둘의 차이는 addEventListener 메서드를 실행할 때 3번째 파라미터 값으로 true/false 중 어떤 것을 주느냐의 차이다.
참고로 false가 디폴트값이고 이는 버블링을 나타낸다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body id="body"> <div id="div"> <p id="p"> <button id="btn"> 캡쳐링과 버블링 </button> </p> </div> </body> <script> let button = document.getElementById("btn"); let p = document.getElementById('p'); let div = document.getElementById('div'); let body = document.getElementById('body'); function ftest(){ console.log("버블링:" + " 일어난 이벤트: "+event.target.nodeName+" 이벤트가 일어나는 현재 노드: "+this.nodeName); } btn.addEventListener('click', ftest, false); p.addEventListener('click', ftest, false); div.addEventListener('click', ftest, false); body.addEventListener('click', ftest, false); </script> </html>
버블링은 아래와 같이 <button> - <p> - <div> - <body> 순으로 이벤트가 실행된다.
2. 버블링과 캡쳐링 중단시키기
버블링, 캡쳐링은 HTML 구조상 자연스럽게 생기는 이벤트의 전파다.
그러나 이벤트 진행상 버블링이나 캡쳐링을 중단해야할 상황도 있다.
그럴 때는 'stopPropagation()' 메서드를 사용하면 된다.
이 때 'stopPropagation' 메서드는 'event' 객체를 이용해서 호출해주면 된다.
참고로 'event' 객체란 이벤트 핸들러를 이용해서 이벤트 코드를 실행할 때 해당 핸들러에 전달되는 객체다.
이 'event' 객체를 이용하면 이벤트와 관련된 다양한 사항을 제어할 수 있다.
코드는 다음과 같다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body id="body"> <div id="div"> <p id="p"> <button id="btn"> 캡쳐링과 버블링 </button> </p> </div> </body> <script> let button = document.getElementById("btn"); let p = document.getElementById('p'); let div = document.getElementById('div'); let body = document.getElementById('body'); function ftest(){ console.log("버블링:" + " 일어난 이벤트: "+event.target.nodeName+" 이벤트가 일어나는 현재 노드: "+this.nodeName); } function stest(){ console.log("버블링:" + " 일어난 이벤트: "+event.target.nodeName+" 이벤트가 일어나는 현재 노드: "+this.nodeName); event.stopPropagation(); } btn.addEventListener('click', ftest, false); p.addEventListener('click', ftest, false); div.addEventListener('click', stest, false); body.addEventListener('click', ftest, false); </script> </html>
'stopPropagation'메서드가 추가된 메서드를 하나 더 만들어줘서 div 단계에서 버블링이 중단되게 했다.
실행 결과는 다음과 같다.
위 코드대로 'stopPropagation()' 메서드가 실행되는 <div> 태그까지만 이벤트가 실행되었다.
'프론트엔드 > JavaScript' 카테고리의 다른 글
이벤트 객체 (0) 2020.10.28 자바스크립트 - 버블링, 캡쳐링의 활용과 이벤트 위임 (0) 2020.10.20 자바스크립트 - 이벤트 핸들러 (0) 2020.10.19 자바스크립트 - 이벤트 (0) 2020.10.19 자바스크립트 고차함수 - find(), findindex() (0) 2020.10.06