WEB/JavaScript

[JavaScript][Event] 버블링, 이벤트가 정확히 어디서 발생했는지 접근할 수 있는 방법

bay07 2024. 4. 22. 14:36

▶ 버블링

한 요소에 이벤트가 발생하면, 이 요소에 할당된 핸들러가 동작하고 
이어서 부모 요소의 핸들러가 동작하는 현상

가장 최상단의 조상 요소 (document)를 만날 때까지 이 과정이 반복되면서 
요소 각각에 할당된 핸들러가 동작한다 

제일 깊은 곳에 있는 요소에서 이벤트가 시작해 
부모 요소를 거슬러 올라가면 발생하는 것이 
마치 물속 거품과 닮았기 때문이다 

가장 안쪽의 <p> 요소를 클릭하면 
p -> div -> form 순서로 
3개의 이벤트 핸들러가 모두 동작했던 것

 


문제의식 ) 

버블링이 나오게 된 상황 

 
 위와 같은 형태의 중첩된 구조에 각각 이벤트 핸들러가 있을 때 
 만약 <p> 요소를 클릭하면 어떻게 될까?
 
<p> 요소만 클릭했는데도 불구하고, 모든 핸들러가 동작한다

Q. 왜 p를 클릭했는데 div와 form에 할당된 핸들러까지 동작할까?

=> 버빌링 


▶ 이벤트가 정확히 어디서 발생했는지 접근할 수 있는 방법 

currentTarget 속성 target 속성
'현재' 요소
항상 이벤트 핸들러가 연결된 요소만을 참조하는 속성
'this'와 같다
이벤트가 발생한 가장 안쪽의 요소(target)을 참조하는 속성
실제 이벤트가 시작된 요소
버블링이 진행되어도 변하지 않는다 
* 주의사항
console.log()로 event 객체를 출력할 경우 currentTarget 키의 값은 null이 된다. currentTarget은 이벤트가 처리되는 동안에만 사용할 수 있기 때문이다. 대신 console.log(event.currentTarget)을 사용하여 콘솔에서 확인할 수 있다. 

currentTarget 이후의 속성 값들은 'target'을 참고해서 사용하자 
 

세 요소 중 가장 최상위 요소인 outerouter 요소에만 핸들러가 부착됨
각 요소를 클릭했을 때 event의 target과 currentTarget의 차이를 비교하기 

currentTarget : 핸들러가 연결된 outerouter 요소만을 가리킨다 
target : 실제 이벤트가 발생하는 요소를 가리킨다 

핸들러는 outerouter에만 할당되어 있지만,
하위 요소 outer와 inner를 클릭해도 해당 핸들러가 동작한다

클릭 이벤트가 어디서 발생했든 상관없이 outerouter까지 
이벤트가 버블링되어 핸들러를 실행시키기 때문이다


버블링이 필요한 이유 

만약 다음과 같이 각자 다른 동작을 수행하는 버튼이 여러개 있다고 가정하자. 
그러면 각 버튼마다 서로 다른 이벤트 핸들러를 할당해야 할까?

=> 각 버튼의 공통 조상인 div 요소에 
이벤트 핸들러를 1개만 할당하면 된다. 




요소의 공통 조상에 
이벤트 핸들러를 단 1개만 할당하면
여러 요소를 한번에 다룰 수 있다. 

공통 조상에 할당한 핸들러에서 event.target을 이용하면 
실제 어떤 버튼에서 이벤트가 발생했는지 알 수 있기 때문이다.

 


참고) 

▷ 캡처링 ★

이벤트가 하위 요소로 전파되는 단계

↔  버블링 ★ ★ ★ ★ ★

table 안에 td를 클릭하면, 이벤트는 최상위 요소부터 아래로 전파된다. 

실제 이벤트가 발생한 지점 (event.target)에서 실행된 후 
다시 위로 전파된다. 
이 과정에서 상위 요소에 할당된 이벤트 핸들러가 호출된다 

캡처링은 실제 다루는 경우가 거의 없으므로 
버블링에 집중하기