브라우저에는 엄청나게 많은 event가 있다. (change, click, mouseover 등등)
이런 event가 발생 했을 때 이렇게 처리해주겠다~ 하는 것이 event handler 이다. = event listener = event 콜백 함수
addEventListener 누구에게 ~가 일어나면 ~ 하겠다!
element.addEventListener, element: 누구에게~ 첫번째 인자가 ~가 일어나면, 콜백함수가 ~ 하겠다.
onclick에도 event handler를 달 수 있지만 좀 옛날 느낌이다. addEventListener를 사용하자. 좀 더 정교하게 컨트롤 할 수 있는 기능 제공. 인자를 3개 받을 수 있다. event type, event handler, 3번째 인자로 어떻게 컨트롤 할건지의 옵션. onclick은 그런게 안 된다.
addEventListener는 여러 개의 event를 달 수 있다. onclick은 한개만 달 수 있다. (하지만 여러 개 달아본적은 없다.)
load 이벤트 resource를 다 불러 왔을 때..
scroll 유저가 스크롤을 할 때
resize 화면을 줄이고 늘리고
blur 포커스를 잃었을 때
focus 포커스를 했을 때
change input, textarea의 값이 바뀌었을 때
submit submit 버튼을 눌렸을 때
click 클릭 했을 때
dbclick 은 버그가 많다.
mousedown mouse가 눌려진 것.
mouseenter 어떤 요소가 마우스가 들어갔냐 진입했냐
mouseleave는 마우스가 들어갔다 나갔냐
mouseup은 마우스를 눌렸다가 땔 때
keydown keyup 특정 키를 눌렀을 때 활용 가능 esc 등
모바일에는 마우스가 없어서 터치를 눌렸따 땠다 움직이다~ 를 touchstart, touchend 등으로 대체
이름이 직관적이라 외울 필요가 없다.
event가 어떤식으로 작동하는지에 대해 이해하고 있어야 한다.
click으로 예시
div를 눌렀는데 div 하나만 눌렀다고 표현하기가 애매하다. div를 감싸고 있는 body, html 요소도 있다. div를 클릭한건가 body를 클릭한 것인가 html을 클릭한 것인가.
그래서 부모 element 들에게도 다 같이 click 이벤트를 발생시킨다. 진짜 event가 발생한 부분은 div가 되고 body, html 또한 이벤트에 탑승한다.
body, html에 click 이벤트가 없으면 아무 상관 없다. 그런데 click event가 달려있으면 문제가 된다.
target이랑 currentTarget을 분리해서 이해해야한다. event.currentTarget은 이벤트의 진짜 주인 즉, 이벤트 handler가 돼있는 것, target은 누구 때문에 event가 일어났는가 이다. 클릭된 녀석.
div를 클릭했을 때 currentTarget div, target도 div
body 입장에서는 body에 있는 click event handle 는 currentTarget은 body 누구 때문에 실행됐냐? div
html에 달린 event handle 도 currentTarget은 html, target은 div
Capture phase: html부터 target phase로 올라가는 것. 발생된 원인인 div가 target phase이다.
Bubble phase: target부터 html로 가는 것
capture → propagate up
Bubble → propagate down
div를 클릭했을 때 body, html에도 클릭 이벤트가 있었다. 하면 html 부터 실행 body 실행 그다음 div가 실행, 그 후 Bubble이 실행되면 body, html 이 또 실행되는~ 그래서 브라우저는 제약을 둔다.
body, html은 양자 택일 너네는 capture 단계에서 실행될래 ~ bubble 단계에서 실행될래~
기본 값은 bubble이다! 클릭 된 녀석이 먼저 실행되는게 맞는거 같다.
Capture → Target → Bubble
Capture 때 실행 될래 하면 Capture 때 실행되고 Target 갔다가 Bubble까지 실행 순서대로 실행된다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 200px;
height: 200px;
background-color: aqua;
}
</style>
</head>
<body>
<div>
div!!
</div>
<script>
const html = document.querySelector('html');
const body = document.querySelector('body');
const div = document.querySelector('div');
div.addEventListener('click', () => {
console.log('div!!')
});
body.addEventListener('click', () => {
console.log('bubble body!')
});
body.addEventListener('click', () => {
console.log('capture body!');
}, true);
html.addEventListener('click', () => {
console.log('bubble html!');
});
html.addEventListener('click', () => {
console.log('capture html!');
}, true)
</script>
</body>
</html>
간단한 코드로 확인해보니 div를 클릭 했을 시 capture phase를 실행하고 target phase 그리고 bubble phase 순서로 실행 된다.
참고자료 김버그님 유튜브
https://www.youtube.com/watch?v=it46nEygRcM&ab_channel=%EA%B9%80%EB%B2%84%EA%B7%B8Kimbug
https://www.youtube.com/watch?v=7gKtNC3b_S8&ab_channel=%EA%B9%80%EB%B2%84%EA%B7%B8Kimbug