<div onclick="alert('div에 이벤트 할당')">
<span>span을 클릭해도 div 이벤트 핸들러가 동작한다.</span>
</div>
onClick
이벤트가 div
에 할당 되어있지만 span
을 클릭해도 동작한다. 동작 원리를 알기 위해 이벤트 버블링과 캡처링에 대해 알아보자.
- 한 요소에 이벤트가 발생하면, 이요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작한다.
- 가장 최상단의 조상 요소를 만날 때까지 이과정이 반복되면서 요소 각각에 할당된 핸들러가 동작한다.
<form onclick="alert('form')">FORM
<div onclick="alert('div')">DIV
<p onclick="alert('p')">P</p>
</div>
</form>
가장 안쪽의 <p>
요소를 클릭시 p
> div
> form
순서로 onclick
핸들러가 동작하여 3개의 alert
창이 뜬다.
가장 깊은 곳에서 부모 요소를 거슬러 올라가는 모양이 물속 거품같아 이런 흐름을 이벤트 버블링
이라고 한다.
이벤트가 발생한 가장 안쪽의 요소는 타깃(target) 요소라 하고, event.target
을 통해 접근 가능하다.
event.target
과 this(=event.currentTarget)
은 차이점이 있다.
<div onclick="alert('이 alert는 실행되지 않는다.')">
<button onclick="event.stopPropagation()">클릭</button>
</div>
event.stopPropagation()
을 통해 이벤트가 실행된 요소에서 더이상 거슬러 올라가지 않고 중단된다.
이벤트 캡처링은 버블링과 반대로 상위에서 자식요소로 전파되는 방식이다.
DOM 이벤트 흐름엔 3가지 단계가 있다
- 캡처링 단계 - 이벤트가 하위 요소로 전파되는 단계
- 타깃 단계 – 이벤트가 실제 타깃 요소에 전달되는 단계
- 버블링 단계 – 이벤트가 상위 요소로 전파되는 단계
캡처링 단계를 이용해야 하는 경우는 흔치 않지만 addEventListener
의 capture
옵션을 true
로 설정을 통해 이벤트를 잡을 수 있다.
element.addEventListener(..., {capture: true})
// 아래와 같이 true를 써줘도 된다.
elem.addEventListener(..., true)
false
이면(default) 핸들러는 버블링 단계에서 동작한다.