하위에서 상위 요소로의 이벤트 전파 방식을 이벤트 버블링(Event Bubbling)이라고 함
<!-- HTML -->
<div class="one">
<div class="two">
<div class="three">three</div>
two
</div>
one
</div>
// javascript
const divs = document.querySelectorAll('div');
divs.forEach((div) => {
div.addEventListener('click', logEvent);
});
function logEvent(e) {
console.log(event.currentTarget.className);
}
아래와 같이 박스 세개가 중첩된 구조를 가질 때
3 depth인, 세 번째 박스를 클릭하면 이벤트 버블링 현상이 일어남으로
three -> two -> one 순서대로 아래에서 위의 순서로 console에
log가 나타나는 것을 볼 수 있다.
이벤트 캡쳐는 이벤트 버블링과 반대 방향으로 진행되는 이벤트 전파 방식입니다.
const divs = document.querySelectorAll('div');
function logEvent(e) {
console.log(event.currentTarget.className);
}
divs.forEach((div) => {
div.addEventListener('click', logEvent, {
capture: true,
});
});
// el.addEventListener(type, listener, options)
이벤트 버블링과 동일한 HTML 구조에서
이벤트 캡쳐 현상을 나타내기 위해 addEventListener
method
의 세번째 매개변수인 option
에 capture : true
를 선언해준다.
capture
옵션을 활성화 해줌으로써 이미지와 같이 위에서 아래로 이벤트를 탐색하는 캡쳐링 현상이 나타나게 되며,
one -> two -> three 순서대로 console에 log가 나타나는 것을 볼 수 있다.
위 API는 현재 발생된 이벤트가 전파되는 것을 막습니다.
그러나 기본 동작이 발생하는 것을 막지는 않습니다.
const divs = document.querySelectorAll('div');
function logEvent(e) {
// 이벤트 위임 방지 메서드
e.stopPropagation();
console.log(event.currentTarget.className);
}
// 이벤트 버블링 테스트
divs.forEach((div) => {
div.addEventListener('click', logEvent);
});
// 이벤트 캡쳐링 테스트
divs.forEach((div) => {
div.addEventListener('click', logEvent, {
capture: true,
});
});
위의 두 사례와 같이 이벤트 버블링(아래->위) 상황이나
이벤트 캡쳐링(위->아래) 상황에서 이벤트 전파를 방지하기 원할 때,
event.stopPropagation()
API를 사용하면
버블링의 경우 각각의 단일요소만, 캡쳐링의 경우 최상단 요소만 선택되는 것을 확인 할 수 있다.
하위 요소에 각각 이벤트를 붙이지 않고 상위 요소에서 하위 요소의 이벤트들을 제어하는 방식
위에서 설명한 이벤트가 위임(버블링, 캡쳐링)되는 속성을 이용하여
최상단 요소에서 addEventListener
를 한번만 사용해도 하위 요소들
이벤트 발생 여부를 한 번에 감지할 수 있다.
<form action="#" id="form">
<input type="text" id="email" placeholder="전화번호, 사용자 이름 또는 이메일" />
<input type="password" id="password" placeholder="비밀번호" />
<button id="btnLogin" disabled>로그인</button>
</form>
const form = document.getElementById('form');
function onHandleInput(e) {
const inputId = e.target.id;
const inputValue = e.target.value;
let id = '';
let pw = '';
if (inputId === 'email') {
id = inputValue;
console.log('id 입력값 :', id);
}
if (inputId === 'password') {
pw = inputValue;
console.log('pw 입력값 :', pw);
}
}
form.addEventListener('input', onHandleInput);
위의 코드는 로그인 페이지에서 폼 핸들링이 필요한 경우 이벤트가 위임되는 것을 사용하여
최상단에서 id와 pw 입력창 이벤트를 핸들링하는 예시코드입니다.
테스트를 해보면 코드상 form에서만 addEventListener로 입력값을 탐색하지만
id와 pw 모두 이벤트 로그가 잘 나오는 것이 보입니다.
*본 포스팅은 아래 포스트 내용을 공부하며 정리한 내용을 기록한 것입니다.