자바스크립트 이벤트 버블링과 캡쳐
자바스크립트 이벤트 버블링과 캡쳐
HTML DOM API에서 이벤트를 전파하는 방법에는 이벤트 캡쳐링과 이벤트 버블링이 있습니다. 이를 간단하게 소개해보겠습니다.
이벤트 캡쳐링
위 사진에서 Capture Phase (1)
에 해당하는 부분이 이벤트 캡쳐링에 해당합니다. 이벤트가 가장 바깥쪽 요소부터 안쪽 요소로 즉, Target Phase (2)
까지 전파가 됩니다.
<div id="parent">
<div id="child">
Click Me
</div>
</div>
<script>
const parent = document.querySelector('#parent');
const child = document.querySelector('#child');
parent.addEventListener('click', () => {
alert('click parent div');
}, true);
child.addEventListener('click', () => {
alert('click child div');
});
</script>
위의 코드에서 'Click Me'를 감싸고 있는 DOM 엘리먼트를 클릭하면 'click parent div', 'click child div' 순서대로 2개의 Alert를 확인할 수 있습니다.
addEventListener의 useCapture 인자
이는 addEventListener
의 3번째 인자 useCapture
를 true
로 설정했기 때문입니다. 3번째 인자를 options
객체로 넘길 수도 있는데, option 값은 다음과 같습니다.
{
capture: boolean;
once: boolean;
passive: boolean;
}
- capture: 값이 true 하면 이벤트 캡쳐링을 합니다.
- once: 값이 true 라면 이벤트가 한 번만 발생됩니다.
- passive: 값이 true 라면 콜백 함수 내부에
preventDefault()
가 있다 하더라도 실행되지 않습니다.
이벤트 버블링
위 사진에서 Bubbling Phase (2)
는 가장 안쪽 요소부터 바깥쪽 요소로 전파가 되는 것을 의미합니다.
웹 페이지 내의 한 엘리먼트가 감지되었을 때, 해당 엘리먼트의 계층 구조를 따라 올라가면서 Root Element까지 이벤트가 전달되는 것을 말합니다.
<div class="root" onclick="alert('3')">
<div onclick="alert('2')">
<div onclick="alert('1')">
Click Me
</div>
</div>
</div>
위의 코드에서 'Click Me'를 감싸고 있는 DOM 엘리먼트를 클릭하면 1, 2, 3 순서대로 3개의 Alert를 확인할 수 있습니다.
하위 DOM Element부터 최종적으로 Document 객체까지 전달되는 특성을 이용해 상위 Element에서 이벤트 핸들러를 재정의해서 이벤트 전파를 제어할 수 있습니다.
'대부분'의 이벤트는 버블링 됩니다
모든 이벤트가 버블링 되는 것은 아닙니다.focus
와 같이 버블링 되지 않는 몇몇 이벤트를 제외한 대부분의 이벤트는 버블링 됩니다.
event.target
부모 Element의 핸들러는 이벤트가 어디에서 발생했는지에 대해 알 수 있습니다. 이벤트가 발생한 Element는 target element라 불리고, event.target
을 통해 접근할 수 있습니다.
event.target과 this(event.currentTarget)
event.target
과 this(event.currentTarget)
에는 다음과 같은 차이가 있습니다.
event.target
은 실세 이벤트가 시작된 'target' element입니다. 이는 버블링이 진행되어서 부모의 이벤트가 실행되어도 변하지 않습니다.this
는 'current' element입니다. 현재 이벤트가 실행 중인 element를 참조합니다.
'이벤트 버블링' 섹션의 예제를 봤을 때, 가장 바깥쪽에 있는 div
의 경우, 모든 child element의 이벤트에 의해 버블링 되어 실행됩니다. 가장 바깥쪽 div
의 이벤트가 실행될 때 event.target
과 this
는 다음과 같습니다.
event,target
: 이벤트가 처음 실행된 'Click Me' 텍스트를 감싸고 있는 div elementthis
: 현재 이벤트가 실행되고 있는 가장 바깥쪽 div element
버블링 중단
<div class="root" onclick="alert('3')">
<div onclick="event.stopPropagation()">
<div onclick="alert('1')">
Click Me
</div>
</div>
</div>
위 코드는 'Click Me' 텍스트를 클릭하더라도 두 번째 div 이상으로 전파되지 않습니다. 이벤트가 발생한 Element의 상위 Element에서 onclick 이벤트를 작성할 때 event.stopPropagation()
함수를 이용해 이벤트 전파를 중단했기 때문입니다.
'Advanced > JavaScript' 카테고리의 다른 글
자바스크립트 이벤트 델리게이션 패턴 (0) | 2020.11.12 |
---|---|
JavaScript 이벤트 전파 중단 방법 (IE 대응 추가) (0) | 2020.11.10 |
JavaScript child element mouseout 이슈 (0) | 2020.10.29 |
var, let, const 각각의 차이점 (0) | 2020.10.18 |
Math.random()은 정말 랜덤일까? (1) | 2020.10.17 |
댓글
이 글 공유하기
다른 글
-
자바스크립트 이벤트 델리게이션 패턴
자바스크립트 이벤트 델리게이션 패턴
2020.11.12 -
JavaScript 이벤트 전파 중단 방법 (IE 대응 추가)
JavaScript 이벤트 전파 중단 방법 (IE 대응 추가)
2020.11.10 -
JavaScript child element mouseout 이슈
JavaScript child element mouseout 이슈
2020.10.29 -
var, let, const 각각의 차이점
var, let, const 각각의 차이점
2020.10.18