ko.javascript.info/bubbling-and-capturing
아래 핸들러는 div에 할당되어 있지만, em, code 같은 중첩 태그를 클릭해도 동작한다.
<div onClick = "alert('hello')">
<em>
<code>
Hi
</code>
</em>
</div>
왜 em을 클릭했는데, div에 할당된 핸들러가 동작하는 것일까?
- 버블링
한 요소에 이벤트가 발생하면, 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작한다.
가장 최상단의 조상요소를 만날 때 까지 이 과정이 반복되면서 요소 각각에 할당된 핸들러가 동작한다.
예를 들어 다음과 같은 경우
<form onClick="alert('form')">
FORM
<div onClick="alert('div')">
DIV
<p onClick="alert('p')">
P
</p>
</div>
</form>
가장 안쪽의 p를 클릭하면, 다음과 같은 동작이 수행된다.
1. p에 할당된 onClick 핸들러가 동작한다.
2. div에 할당된 핸들러가 동작한다.
3. form에 할당된 핸들러가 동작한다.
4. document 객체를 만날때까지 각 요소에 할당된 onClick핸들러가 동작한다.
이것을 이벤트 버블링이라고 부른다.
이벤트가 제일 깊은 곳에 있는 요소에서 시작해 부모 요소를 거슬러 올라가며 발생하는 모양이 마치 거품과 닮았기 때문에 그런 명칭이 붙여졌다고 한다.
+ 대부분의 이벤트는 버블링된다.
focus 이벤트 같은것은 버블링되지 않는다.
- event.target
부모 요소의 핸들러는 이벤트가 정확히 어디서 발생하는지 등에 대한 자세한 정보를 얻을 수 있다.
이벤트가 발생한 가장 안쪽의 요소는 target 요소라고 불리고, event.target을 사용해 접근할 수 있다.
- 버블링 중단하기
이벤트 버블링은 타깃 이벤트에서 시작해서 html요소를 거쳐 document 객체를 만날때까지 각 노드에서 모두 발생한다.
그러면 버블링을 중단하기 위해서는 어떻게 해야할까?
event.stopPropagation() 을 사용하면된다.
아래 예시에서는 button을 클릭해도 body.onClick이 동작하지 않는다.
<body onClick="alert('A')">
<button onClick="event.stopPropagation()">
Hi
</button>
</body>
하지만 event.stopPropagation도 한계가 있는데
위쪽으로 일어나는 버블링은 막아주지만, 현재 다른 핸들러들이 동작하는 것은 막지 못한다는 것이다.
버블링을 멈추고 요소에 할당된 다른 핸들러의 동작도 막으려면
event.stopImmediatePropagation을 사용해야 한다.
- 되도록 버블링을 막지말자
이벤트 버블링을 막아야 하는 경우는 거의없는데, 꼭 버블링을 막아야 해결되는 문제라면
커스텀 이벤트 등을 이용해 문제를 해결할 수 있다.
'개발 > FrontEnd Interview' 카테고리의 다른 글
[Frontend Interview] .call과 .apply의 차이점은? (0) | 2021.01.17 |
---|---|
[Frontend Interview] 캡처링 (0) | 2021.01.15 |
[Frontend Interview] inline과 inline-block의 차이점 (0) | 2021.01.14 |
[Frontend Interview] float는 어떻게 동작하는가? (0) | 2021.01.09 |
[Frontend Interview] Resetting, Normalizing CSS의 차이점은? (0) | 2021.01.09 |