[JS] 너 EventFlow라고 알아? - Capture, Bubble 편

devicii·2021년 5월 20일
1

javascript

목록 보기
4/7

자주 쓰면서 잘 모르고 있던 event의 디테일을 알아보자.

우리가 자바스크립트 이벤트 예제를 만들어 실행했을 때 사실 구조는 이렇게 짜인다. 이벤트의 시작점은 div태그이지만, div가 클릭될 때 부모인 body와 html도 이벤트에서 피해갈 수 없다.
자바스크립트식 연좌제이다.

target VS currentTarget

자주 쓰지만 상당히 헷갈리는 개념이다.
이미지에서 보듯이 target은 이벤트가 실행된 대상이고, currentTarget은 실행한 대상이 아닌 이벤트를 실행하게 한 대상이다.

Event flow

Capture -> Target -> Bubble

이벤트는 일정한 실행 과정을 가지게 된다.
여기서 보면 div를 클릭할 시, 최상단의 html -> body -> div 순으로 Capture과정을 거치게 된다. 그 이후에는 실행한 div의 Target과정 이후 다시 반대로 최하단 div -> body -> html 순으로 역순으로 거치게 된다. 여기서 중요한 점은 Capture과정은 default가 false이다.
그래서 Target과정 -> Bubble과정 순으로 기본적으로 진행된다.

예제


const body = document.querySelector('body')
const html = document.querySelector('html')
const button = document.querySelector('.button')

body.addEventListener('click', () => {
	console.log('body')
})

html.addEventListener('click', () => {
	console.log('html')
})

button.addEventListener('click', () => {
	console.log('button')
})

이렇게 분명 button만 클릭했는데도 body와 html도 함께 나온다.
이유는 위에서 봤던 것처럼 이벤트 버블링이 일어나기 때문이다.


const body = document.querySelector('body')
const html = document.querySelector('html')
const button = document.querySelector('.button')

body.addEventListener('click', () => {
	console.log('body')
}, true)

html.addEventListener('click', () => {
	console.log('html')
})

button.addEventListener('click', () => {
	console.log('button')
})

이렇게 인자로 true를 준다면 capture를 true바꾼 것이라,
body -> button -> html순으로 실행되게 된다.

stopPropagation ()

body.addEventListener('click', (e) => {
	console.log('body')
   e.stopPropagation( )
}, true)

html.addEventListener('click', () => {
	console.log('html')
})

button.addEventListener('click', () => {
	console.log('button')
})

결과 : body

stopPropagation()함수는 이벤트 전달을 막아버리는 메소드이다.
여기서 결과가 왜 body만 나오냐면 eventFlow를 다시 생각해보자.
button을 클릭해서 htm -> body로 capture이 실행되던 중 갑자기 body에서 stopPropagatio()을 만난다면 어이없게도 거기서 그냥 종료가 돼버린다. taget -> bubble순서가 사라지게 되어서 body만 나오게 된다.

참고자료

김버그님 유튜브 강의

profile
Life is a long journey. But code Should be short :)

0개의 댓글