프론트엔드 개발자라면 addEventListener를 어떻게 사용하는지 알 뿐만 아니라
이벤트가 어떻게 동작하는지도 알고 있어야 한다!
가장 직관적인 click 이벤트로 예시를 들어보겠습니다.
❓ 뭐가 문제야?
<html> <body> <div></div> </body> </html>
const div = document.querySelector('div'); div.addEventListener('click', something)
이벤트가 걸린 div를 클릭하면 무슨 일이 일어날까?


- div는 이벤트가 실행되는 직접적인 요소.
- div 하나만 눌렀다고 말할 수 있을까? 만약 부모들에게도 똑같이 click 이벤트가 있다면?
- 정답은 다같이 실행한다!
- 이벤트가 적용 대상에 바로 실행되는 것이 아닌 순차적으로 실행되는 것이 생김 → evnet flow를 가진다!
여기서 중요한 용어 정리!

- current target : 이벤트의 진짜 주인.
- target : 이벤트의 시발점.
- 이 둘을 분리해서 생각해야 함.
🤔 어떻게 실행되는데?
- event flow는 흐름이 정해져 있음.
- 브라우저에서 가장 가까이 있는 곳(HTML)부터 시작됨 → Capture phase
- 이벤트의 당사자가 실행이 됨 → Target phase
- 다시 내려옴 → bubble phase

- 아까와 같이 div, body, html 모든 요소에 이벤트가 걸려있다면 모두 실행될 것임.
그럼 이렇게 하자!
- currentTarget과 target이 일치하지 않을 경우, 캡쳐단계 또는 버블단계에서 발생될지 선택할 수 있음.
- 기본 값은 버블임. div에 이벤트를 걸고 싶은데 브라우저 상단부터 실행되면 합리적이지 않기 때문.

💡 직접 실행해보자

<html> <body> <div></div </body> </html>
const html = document.documentElement const body = document.body const div = document.querySelector('div'); div.addEventListener('click', function() { console.log('div다') }) body.addEventListener('click', function() { console.log('body다') }) html.addEventListener('click', function() { console.log('html이다') })
const html = document.documentElement const body = document.body const div = document.querySelector('div'); div.addEventListener('click', function() { console.log('div다') }) body.addEventListener('click', function() { console.log('body다') }, true) html.addEventListener('click', function() { console.log('html이다') })


😟 매번 신경써야 할까?
- 웬만하면 버블링을 기본으로 실행하기 때문에 걱정 안해도 됨.
- 하지만 미세한 이벤트 control이 필요할 땐 true로 바꿀 수 있는 우아함을 기르자.
- 브라우저의 이벤트 flow는 막을 수 없지만 propagation의 전파는 막을 수 있음.
Event.stopPropagation()
: 이벤트 캡쳐링과 버블링에 있어 현재 이벤트 이후의 전파를 막음.
- 실무에선 이벤트를 중첩시킬 일이 많지 않기 때문에 임시로 사용하거나 이벤트를 막는 용도로 사용하기도 함.
const html = document.documentElement const body = document.body const div = document.querySelector('div'); div.addEventListener('click', function(e) { e.stopPropagation() console.log('div다') }) body.addEventListener('click', function() { console.log('body다') }) html.addEventListener('click', function() { console.log('html이다') })

그 외의 event control
Event.preventDefault()
: 이벤트를 취소할 수 있는 경우, 이벤트의 전파를 막지않고 그 이벤트를 취소함.
- JS는 이렇게 HTML을 자유롭게 컨트롤할 수 있지만 markup을 등한시해선 안됨. 시멘틱하게 짜는 것이 좋음.
const form = document.querySelector('form') form.addEventListener('submit', function(e){ e.preventDefault() })
참고자료 :