[JS] 이벤트 전파 / 이벤트 버블링 / 이벤트 캡처링

반응형

이벤트 전파 (Event Phase)

브라우저에서 html 요소에 이벤트가 발생할 때, 이벤트가 전파되는 흐름에 따라 이벤트 버블링이벤트 캡처링이 발생함

<!DOCTYPE html> <html lang="en"> <head> ​​​​<meta charset="UTF-8"> ​​​​<title>Event</title> </head> <body> body 영역 ​​​​<main> main 영역 ​​​​​​​​<div> div 영역 ​​​​​​​​​​​​<p> p 영역 ​​​​​​​​​​​​​​​​<span>span 영역</span> ​​​​​​​​​​​​</p> ​​​​​​​​</div> ​​​​</main> </body> </html>

 

01) 이벤트 버블링 (Event Bubbling)

이벤트 버블링은 이벤트 타깃 요소에서부터 최상위 요소인 html 문서까지 이벤트가 전파되는 것으로,

addEventListener 이벤트는 기본적으로 버블링으로 동작함

<script> ​​​​const $body = document.querySelector('body'); ​​​​const $main = document.querySelector('main'); ​​​​const $div = document.querySelector('div'); ​​​​const $p = document.querySelector('p'); ​​​​const $span = document.querySelector('span'); ​​​​$span.addEventListener('click', function () { ​​​​​​​​console.log('span 태그') ​​​​}); ​​​​$p.addEventListener('click', function () { ​​​​​​​​console.log('p 태그') ​​​​}); ​​​​$div.addEventListener('click', function () { ​​​​​​​​console.log('div 태그') ​​​​}); ​​​​$main.addEventListener('click', function () { ​​​​​​​​console.log('main 태그') ​​​​}); ​​​​$body.addEventListener('click', function () { ​​​​​​​​console.log('body 태그') ​​​​}); </script>

span 태그를 클릭했을 때 consolg 창 (bubbling)

  • 위의 script 코드를 추가해서 console 창을 확인하면, span 태그를 클릭했을 때 span에서부터 body 태그까지 이벤트가 전파되는 과정을 확인할 수 있음

 

02) 이벤트 캡처링 (Event Capturing)

이벤트 캡처링은 최상위 요소(html)에서 해당 이벤트 타깃 요소까지 이벤트가 전파되는 것으로,

addEventListener 이벤트에 true 값을 설정하여 캡처링으로 변경할 수 있음 (기본값 : false)

<script> ​​​​const $body = document.querySelector('body'); ​​​​const $main = document.querySelector('main'); ​​​​const $div = document.querySelector('div'); ​​​​const $p = document.querySelector('p'); ​​​​const $span = document.querySelector('span'); ​​​​// capturing ​​​​$span.addEventListener('click', function () { ​​​​​​​​console.log('capturing span 태그') ​​​​}, true); ​​​​$p.addEventListener('click', function () { ​​​​​​​​console.log('capturing p 태그') ​​​​}, true); ​​​​$div.addEventListener('click', function () { ​​​​​​​​console.log('capturing div 태그') ​​​​}, true); ​​​​$main.addEventListener('click', function () { ​​​​​​​​console.log('capturing main 태그') ​​​​}, true); ​​​​$body.addEventListener('click', function () { ​​​​​​​​console.log('capturing body 태그') ​​​​}, true); </script>

span 태그를 클릭했을 때 console 창 (capturing)

  • 이벤트 핸들러에 true 값을 추가하면, 최상위 요소부터 이벤트가 전파되는 것을 볼 수 있음

 

03) Event.eventPhase

eventPhase는 이벤트 핸들러에서 현재 평가 중인 이벤트 흐름 단계를 나타내는 것으로, 정수 값을 반환

<script> ​​​​const $body = document.querySelector('body'); ​​​​const $main = document.querySelector('main'); ​​​​const $div = document.querySelector('div'); ​​​​const $p = document.querySelector('p'); ​​​​const $span = document.querySelector('span'); ​​​​// capturing ​​​​$span.addEventListener('click', function () { ​​​​​​​​console.log('['+ event.eventPhase + '] capturing span 태그') ​​​​}, true); ​​​​$p.addEventListener('click', function () { ​​​​​​​​console.log('['+ event.eventPhase + '] capturing p 태그') ​​​​}, true); ​​​​$div.addEventListener('click', function () { ​​​​​​​​console.log('['+ event.eventPhase + '] capturing div 태그') ​​​​}, true); ​​​​$main.addEventListener('click', function () { ​​​​​​​​console.log('['+ event.eventPhase + '] capturing main 태그') ​​​​}, true); ​​​​$body.addEventListener('click', function () { ​​​​​​​​console.log('['+ event.eventPhase + '] capturing body 태그') ​​​​}, true); ​​​​// bubbling ​​​​$span.addEventListener('click', function () { ​​​​​​​​console.log('['+ event.eventPhase + '] bubbling span 태그') ​​​​}); ​​​​$p.addEventListener('click', function () { ​​​​​​​​console.log('['+ event.eventPhase + '] bubbling p 태그') ​​​​}); ​​​​$div.addEventListener('click', function () { ​​​​​​​​console.log('['+ event.eventPhase + '] bubbling div 태그') ​​​​}); ​​​​$main.addEventListener('click', function () { ​​​​​​​​console.log('['+ event.eventPhase + '] bubbling main 태그') ​​​​}); ​​​​$body.addEventListener('click', function () { ​​​​​​​​console.log('['+ event.eventPhase + '] bubbling body 태그') ​​​​}); </script>

span 태그를 클릭했을 때 console 창 (eventPhase)

  • 반환값이 1일 때 : 부모객체를 통해서 타켓 이벤트까지 전달한 경우
  • 반환값이 2일 때 :현재 타켓 이벤트인 경우
  • 반환값이 3일 때 : 타켓 이벤트에서 부모 객체로 전달한 경우

 

04) 이벤트 방지

이벤트를 차단하고 싶을 때 메서드를 사용하여, 이벤트를 막을 수 있음

 

🔻stopPropagation() : 현재 이벤트가 발생한 요소에서 상위 요소로의 전파를 중단함

<script> ​​​​$span.addEventListener('click', function () { ​​​​​​​​event.stopPropagation(); ​​​​​​​​console.log('['+ event.eventPhase + '] bubbling span 태그') ​​​​}); </script>

span 태그를 클릭했을 때 console 창 (stopPropagation)

  • bubbling span 태그에서 이벤트가 중단되어 더 이상 실행하지 않음

 

🔻preventDefault() : 해당 html 요소에 대한 기본 동작을 실행하지 않도록 지정

<!DOCTYPE html> <html lang="en"> <head> ​​​​<meta charset="UTF-8"> ​​​​<title>Event</title> </head> <body> ​​​​<a href="http://peazh.tistory.com">블로그 이동</a> ​​​​<script> ​​​​​​​​const $a = document.querySelector('a'); ​​​​​​​​$a.addEventListener('click', function () { ​​​​​​​​​​​​event.preventDefault(); ​​​​​​​​}) ​​​​</script> </body> </html>
  • a 태그의 링크를 클릭했을 때, 원래는 페이지가 이동해야 하지만 메서드를 사용하여 이동하지 않음
반응형

댓글