Thief of Wealth

ko.javascript.info/bubbling-and-capturing

 

버블링과 캡처링

 

ko.javascript.info

 

아래 핸들러는 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을 사용해야 한다.

 

- 되도록 버블링을 막지말자

이벤트 버블링을 막아야 하는 경우는 거의없는데, 꼭 버블링을 막아야 해결되는 문제라면

커스텀 이벤트 등을 이용해 문제를 해결할 수 있다.

profile on loading

Loading...