버블링
위의 이미지와 같이 버블링은 이벤트가 발생한 요소부터 위로 올라간다.
<form onclick="alert('form')">FORM
<div onclick="alert('div')">DIV
<p onclick="alert('p')">P</p>
</div>
</form>
만약 p태그를 클릭해도 form 태그에 할당된 핸들러가 동작되는 것을 말한다.
가장 안쪽의 p 태그를 클릭하면 p에 할당된 onclick 핸들러가 동작하고,
그 바깥의 div태그의 핸들러가 동작한다. 그리고 from에 할당된 핸들러가 동작한다.
document 객체를 만날때까지, 각 요소에 할당된 onclick 핸들러가 동작한다.
p를 클릭한다면 p, div, form 의 얼럿창이 순서대로 뜨게 되는 것이고 div 를 클릭한다면 div, form 순으로 얼럿창이 뜨게 되는 것이다.
이것은 event.target을 이용하여 접근할 수 있다.
event.target
이벤트가 발생한 가장 안쪽의 요소는 타깃(target) 요소라고 불리고, event.target을 사용해 접근 할 수 있다.
event.target은 실제 이벤트가 시작된 '타깃' 요소로 버블링이 진행되어도 변하지 않는다.
this는 '현재'요소로, 현재 실행중인 핸들러가 할당된 요소를 참조한다.
event.target과 this의 차이점
event.target
- 이벤트 핸들러 내부에서 이벤트가 발생한 요소를 가리키며, 버블링이 진행되어도 항상 이벤트가 발생된 요소를 가리킨다.
- 주로 이벤트 위임패턴을 사용할때 유용하게 사용한다.
this
- 이벤트 핸들러 내부에서 해당 핸들러를 호출한 요소를 가리킨다.
- 주로 이벤트 핸들러 함수 내부에서 해당 요소의 속성이나 데이터에 접근할 때 사용된다.
- event.target은 버블링되어도 항상 이벤트가 발생된 요소를 가리키지만, this는 해당 함수를 호출한 객체를 가리킨다.
결론적으로 event.target은 실제로 이벤트가 발생한 요소를 가리키고, this는 이벤트 핸들러를 호출한 요소를 가리킨다.
이벤트 위임 (Event Delegation)
이벤트 위임이란 JavaScript를 사용하여 여러개의 하위 요소에 이벤트 핸들러를 할당하는 대신, 하나의 상위 요소에 이벤트 핸들러를 할당하는 패던이다. 이 패턴은 웹 페이지에서 많은 수의 요소에 대한 이벤트 처리를 효율적으로 관리할 수 있게 해준다.
예시코드
document.getElementById('list-container').addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
console.log('Clicked list item:', event.target.textContent);
}
});
'list-conatiner' 라는 상위 요소에 클릭 이벤트를 할당하고, 클릭된 요소가 'LI'인 경우에만 동작을 처리한다.
이런식으로 작성하면 리스트의 항목이 얼마나 많든 하나의 핸들러만 사용하여 이벤트를 처리할 수 있다.
버블링 중단하기
이벤트 버블링은 타깃 이벤트가 시작한 부분부터 document 객체를 만날때까지 각 노드에서 모두 발생하게 된다.
몇몇 이벤트는 window 객체까지 거슬로 올라가기도 하기 때문에, 이것을 중단하도록 명령할 수 있다.
<body onclick="alert(`버블링은 여기까지 도달하지 못합니다.`)">
<button onclick="event.stopPropagation()">클릭해 주세요.</button>
</body>
다음과 같이 event.stopPropagation() 을 사용하여 버블링을 중단 시킬 수 있다.
캡처링
캡처링은 버블링과 반대로 window로부터 이벤트가 발생한 요소까지 이벤트를 전파시키는 것이다.
주로 코드에서 사용하는 부분은 버블링 단계로 버블링과 함께 반대되는 개념으로 알고 있으면 된다.
이벤트가 발생하면 크게 3단계로 나눌 수 있는데,
- 캡처링 단계 – 이벤트가 하위 요소로 전파되는 단계
- 타깃 단계 – 이벤트가 실제 타깃 요소에 전달되는 단계
- 버블링 단계 – 이벤트가 상위 요소로 전파되는 단계
로 나뉜다.
캡처링단계에서 이벤트를 잡아내고 싶다면,
elem.addEventListener(..., {capture: true})
// or
elem.addEventListener(..., true)
와 같이 true로 설정하면 (default 는 false => 버블링) 된다.
캡처링 단계에서도 중단하고 싶다면 event.stopPropagation() 를 사용하면 된다.
🔗 참고
https://mygumi.tistory.com/315
https://ko.javascript.info/bubbling-and-capturing
'Front-End > JavaScript' 카테고리의 다른 글
[비교] Callback함수, Promise함수 (0) | 2023.08.24 |
---|---|
[JS기본] 인터프리터, 호이스팅, 스코프, 렉시컬 환경, 엄격모드, 가비지 컬렉터 등 (0) | 2023.08.22 |
(JavaScript) This, Binding (0) | 2023.01.05 |
(JavaScript)NPM과 NPX에 대해 쉽고 얕게 이해하기 (0) | 2022.12.27 |
(swiper)이미지 슬라이드 만들기 (0) | 2022.12.18 |