
무언가 일어났다는 신호!
이벤트가 발생했을 때 실행되는 함수인 핸들러(handler)를 할당해야 한다
<div onClick={() => alert("div에 연결된 핸들러!")}>
<span>click</span>
</div>
span 태그를 클릭했는데 div에 연결된 핸들러가 동작한다.
이것은 버블링(bubbling) 때문이다.
한 요소에 이벤트가 발생하면, 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작한다. 가장 최상단의 조상 요소를 만날 때까지 이 과정이 반복되면서 요소 각각에 할당된 핸들러가 동작한다.
<form onClick="alert('form')">
FORM
<div onClick="alert('div')">
DIV
<p onClick="alert('p')">P</p>
</div>
</form>

가장 안쪽의 <p>를 클릭하면 순서대로 다음과 같은 일이 발생한다
<p>에 할당된 onclick 핸들러가 동작한다<div>에 할당된 onclick 핸들러가 동작한다<form>에 할당된 onclick 핸들러가 동작한다document 객체를 만날 때까지 각 요소에 할당된 onclick 핸들러가 동작한다몇몇 이벤트를 제외하고 대부분의 이벤트는 버블링된다
p 클릭 → target은 현재 클릭된 <p>가 되고, currentTarget은 <form>이 된다
div 클릭 → target은 현재 클릭된 <div>가 되고, currentTarget은 <form>이 된다
form 클릭 → target은 현재 클릭된 <form>이 되고, currentTarget은 <form>이 된다
target은 이벤트가 처음 발생한 요소, currentTarget은 현재 실행 중인 이벤트 핸들러가 붙어있는 요소이다. target은 변하지 않지만, currentTarget은 이벤트가 전파되면서 핸들러가 실행되는 요소에 따라 계속 변하는 게 핵심이다
이벤트 버블링은 target 이벤트에서 <html> 요소를 거쳐 document 객체를 만날 때까지 각 노드에서 모두 발생한다. 모든 이벤트가 호출되는 것이다.
하지만 핸들러에게 이벤트를 완전히 처리하고 난 후 버블링을 중단하도록 명령할 수 있다.
이벤트 객체의 메서드인 event.stopPropagation()를 사용하면 된다
<form onClick="alert('form')">
FORM
<div onClick="alert('div')">
DIV
<p onClick="event.stopPropagation()">P</p>
</div>
</form>

p를 클릭하면 아무일도 일어나지 않는다
표준 DOM 이벤트에서 정의한 이벤트 흐름 3가지
캡처링 단계에서 이벤트를 잡아내려면 addEventListner의 capture 옵션을 true로 설정해야 한다
for (let elem of document.querySelectorAll("*")) {
elem.addEventListener(
"click",
(event) => alert(`캡처링 : ${event.currentTarget.tagName}`),
{ capture: true }
);
elem.addEventListener("click", (event) =>
alert(`버블링 : ${event.currentTarget.tagName}`)
);
}

p를 클릭하면 다음과 같은 순서로 이벤트가 전달된다
HTML → BODY → FORM → DIV (캡처링 단계)P (타깃 단계)DIV → FORM → BODY → HTML (버블링 단계)이벤트 버블링을 이용하여 이벤트 위임 패턴을 만들 수 있다
예시) 반복되는 자식 요소의 이벤드 핸들러를 부모 요소에 옮겨놓고, 이벤트가 어디서 일어났는지 event.target으로 파악한 후 해당 자식 요소에서 핸들러 실행. 반복되는 리스트나 테이블에 활용할 수 있음
target과 currentTarget을 정확히 파악하여 부모 요소에서 이벤트를 한꺼번에 처리하는 최적화된 코드를 만들 수 있다