웹 프로그래밍에서 이벤트는 사용자의 행동(클릭, 키보드 입력 등) 또는 시스템의 변경에 응답하는 주요 방법이다. 이벤트를 잘 이해하고 활용하면 동적인 사용자 경험을 제공할 수 있다.
이벤트 전파는 이벤트가 어떻게 DOM 트리를 따라 흐르는지를 설명하는 개념이다. 이벤트 전파에는 주로 캡처링 와 버블링이 있다.
예시:
const divArea = document.querySelector("div");
const spanArea = document.querySelector("span");
const btnArea = document.querySelector("button");
divArea.addEventListener("click", funArea);
spanArea.addEventListener("click", funArea);
btnArea.addEventListener("click", funArea);
function funArea(event) {
console.log(event.currentTarget);
}
div
, span
, button
요소에 클릭 이벤트 리스너를 추가하고 해당 요소를 콘솔에 출력하는 함수를 연결되면 다음 순서 같이 출력된다.
funArea
가 호출되어 button
요소가 콘솔에 출력.span
에 전파되고 funArea
가 호출되어 span
요소가 콘솔에 출력.div
에 전파되고 funArea
가 호출되어 div
요소가 콘솔에 출력.이런 식으로 이벤트는 가장 안쪽 요소에서 시작해서 바깥쪽 요소로 전파되는데, 이 과정을 버블링이라고고 한다.
버튼 클릭 했을때 버튼의 이벤트만 발생하고 싶다면 이벤트 전파 중단을 할수 있다.
function funArea(event) {
event.stopPropagation();
console.log(event.currentTarget);
}
button
요소에 클릭 이벤트 해당영역을 콘솔에 출력하는 함수에 event.stopPropagation();
넣으면 이벤트 전파를 막을수 있다. 그러므로 콘솔창에는 button 요소만 출력하게 된다.
const divArea = document.querySelector("div");
const spanArea = document.querySelector("span");
const btnArea = document.querySelector("button");
divArea.addEventListener("click", funArea, { capture: true });
spanArea.addEventListener("click", funArea, { capture: true });
btnArea.addEventListener("click", funArea, { capture: true });
function funArea(event) {
console.log(event.currentTarget);
}
이벤트 캡처링은 이벤트가 가장 바깥쪽의 부모에서 시작하여 실제 이벤트가 발생한 요소까지 전달되는 단계이다. 이 단계에서 이벤트 리스너를 등록하려면 addEventListener
의 세 번째 인수로 true
를 전달하면 된다.
캡처링 단계 이해하기
window
또는 document
에서 시작할 수 있다.JavaScript에서 이벤트 리스너를 추가할 때 세 번째 매개변수로 capture 에 true
를 전달하면, 해당 리스너가 캡처링 단계에서 실행되도록 설정할 수 있다. default 값은 false 이다.
const divArea = document.querySelector("div");
const spanArea = document.querySelector("span");
const btnArea = document.querySelector("button");
divArea.addEventListener("click", funArea, { capture: true });
spanArea.addEventListener("click", funArea, { capture: true });
btnArea.addEventListener("click", funArea, { capture: true });
function funArea(event) {
console.log(event.currentTarget);
}
캡처링은 일반적으로 특정 요소에서 이벤트를 처리하기 전에 이벤트를 가로채야 할 때 유용하다. 예를 들어, 페이지의 모든 클릭 이벤트를 로깅하거나 특정 조건에서 이벤트 전파를 중단해야 할 때 캡처링을 사용할 수 있다.
이벤트 타깃은 실제 이벤트가 발생한 요소를 가리킨다. event.target
을 통해 접근할 수 있으며, 이를 활용하면 동적인 이벤트 처리가 가능하다.
이벤트 버블링은 이벤트가 실제 발생한 요소에서 시작하여 가장 바깥쪽의 부모까지 전달되는 단계이다. 일반적으로 이벤트 리스너는 이 단계에서 등록된다.
요약
이벤트 제어 이유
⇒연속하여 발생한 이벤트 중
마지막(또는 처음) 이벤트만 호출
Debounce란?
Debounce는 주로 이벤트 핸들링에서 사용되는 프로그래밍 패턴 중 하나로, 이벤트가 연속적으로 발생할 경우 일정 시간 동안 이벤트를 그룹화하여 한 번만 실행되게 하는 기법이다. 예를 들어, 사용자가 입력을 하는 동안 계속 이벤트를 발생시키지 않고, 일정 시간동안 키 입력이 없을 때 한 번만 이벤트를 처리하도록 하는 것이다.
Debounce 작동 원리
사용 사례
JavaScript에서 Debounce 구현하기
//<input type="text" id="search" />
let timer;
document.getElementById("search").addEventListener("keyup", function () {
clearTimeout(timer); // 이미 예약된 타이머가 있다면 취소
timer = setTimeout(() => {
console.log("입력 완료:", this.value); // 입력이 완료된 값을 출력
}, 300); // 300ms 동안 추가 입력이 없으면 실행
});
Debounce는 이벤트가 빈번하게 발생하는 상황에서 성능 최적화와 서버 자원 절약 등 다양한 이점을 제공한다. 특히 사용자 인터페이스의 반응성을 유지하면서도 불필요한 연산을 줄일 수 있는 효과적인 방법이다
**Throttle이란?**
Throttle은 주로 이벤트가 너무 자주 발생하는 것을 제한하는 기법이다. 일정 시간 동안 한 번만 실행되게 만드는 기술이다. 이는 빠르게 연속해서 발생하는 이벤트를 제어할 때 유용하다.
//<button id="clickMe">클릭하세요</button>
let isThrottled = false;
document.getElementById("clickMe").addEventListener("click", function () {
if (isThrottled) return; // isThrottled가 true라면 함수 실행을 중단
isThrottled = true; // isThrottled를 true로 설정해 이벤트가 반복 실행되지 않도록 함
console.log("버튼 클릭됨!");
setTimeout(() => {
isThrottled = false; // 일정 시간 후 isThrottled를 false로 설정해 다음 클릭을 허용
}, 1000); // 1초의 지연 시간
});
button
을 연타라 쳐도 1초 간격으로 "버튼 클릭됨!"이 콘솔 창 출력된 것을 볼 수 있다.
Throttle은 이벤트의 과도한 발생을 제한하여 성능 문제를 예방하고, 사용자 경험을 향상시키는 데 유용하다. Debounce와 비슷한 개념이지만, Debounce는 마지막 이벤트가 발생한 후 일정 시간이 지나야 실행되는 반면, Throttle은 일정 시간 간격으로 규칙적으로 실행되는 차이가 있다.
이벤트는 웹 애플리케이션에서 중요한 역할을 하며, 이벤트 전파, 타깃, 버블링, debounce, throttle 등의 개념은 이벤트를 더 효과적으로 다루는 데 중요하다. 이러한 기술을 잘 활용하면 사용자와의 상호작용을 더 풍부하고 반응성 있게 만들 수 있다.