이벤트 핸들링(Event Handling)
핸들러(handler): 사용자의 행동에 어떻게 반응할지를 자바스크립트 코드로 표현한 것
이벤트 핸들링 3가지 방법
- HTML 속성
: HTML 태그 안에 속성으로 할당
(ex. onclick="handler()")
- 잘 사용하지 않음❌ - DOM 프로퍼티
: 이벤트를 함수로 DOM 프로퍼티에 할당
(ex. element.onclick = handler)
- 복수 할당이 불가능❌ - 메서드
: `addEventListener`, `remoceEventListener`
(ex. element.addEventListener(event, handler[, phase]))
이벤트 추가/제거
addEventListener
: 특정 이벤트가 발생했을 때 실행될 함수를 등록
element.addEventListener(event, handler, [options]);
- event: 이벤트 이름(예: "click")
- handler: 핸들러 함수
- options: 프로퍼티를 갖는 객체
- 핸들러 여러 개 할당 가능⭕
- 무조건 addEventListener를 써야 하는 특정 이벤트가 있다.
removeEventListener
: 등록된 이벤트 핸들러를 제거
element.removeEventListener(event, handler, [options]);
- 핸들러를 삭제하려면 핸들러 할당 시 사용한 함수를 그대로 전달해야 한다.
삭제 ❌
elem.addEventListener( "click" , () => alert('감사합니다!'));
// ....
elem.removeEventListener( "click", () => alert('감사합니다!'));
삭제 ⭕
function handler() {
alert( '감사합니다!' );
}
input.addEventListener("click", handler);
// ....
input.removeEventListener("click", handler);
예시
<button id="myButton">클릭하세요</button>
<button id="removeButton">이벤트 제거</button>
<script>
// 버튼 요소 선택
const button = document.getElementById('myButton');
const removeButton = document.getElementById('removeButton');
// 이벤트 핸들러 함수 정의
function handleClick(event) {
alert('버튼이 클릭되었습니다!');
}
// 이벤트 핸들러 등록
button.addEventListener('click', handleClick);
// 이벤트 핸들러 제거 함수
function removeClickEvent() {
button.removeEventListener('click', handleClick);
alert('클릭 이벤트가 제거되었습니다.');
}
// 이벤트 핸들러 제거 버튼에 이벤트 등록
removeButton.addEventListener('click', removeClickEvent);
</script>
이벤트 처리 성능 향상 메서드
👉 함수를 제어하여 불필요한 호출을 줄이는 데 사용
throttle()
: 함수를 일정한 시간 간격으로 실행되도록 제한
- 짧은 시간에 여러 번 발생할 수 있는 이벤트(스크롤 이벤트, 윈도우 리사이즈 이벤트 등)에 사용
- 수도꼭지를 살짝 틀어서 물이 똑똑 떨어지게 하는 것! 💧
- 물을 아끼기 위해 일정한 간격으로 떨어지도록 하는 것처럼, 함수를 일정 시간마다 한 번씩만 실행
function throttle(func, limit) {
let lastFunc;
let lastRan;
return function() {
const context = this;
const args = arguments;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function() {
if ((Date.now() - lastRan) >= limit) {
func.apply(context, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
window.addEventListener('resize', throttle(function() {
console.log('Window resized');
}, 200));
// 윈도우가 리사이즈될 때마다 콘솔에 메시지를 출력하는데, 리사이즈 이벤트는 2초마다 한 번씩만 실행
debounce()
: 특정 시간 동안 반복되는 호출을 하나로 묶어 마지막 호출 후 실행
- 사용자의 입력이 끝난 후에 처리하고 싶을 때(검색창에 키를 입력할 때, 입력이 끝난 후에만 서버 요청을 보내게 하는 경우)에 사용
- 이벤트의 반복 처리를 막기 위해 사용
- 특정 동작이 끝난 후에야 함수를 실행 - 양치질을 하다가 물을 사용하고 싶을 때, 손을 씻으려고 하는 순간마다 물이 켜졌다 꺼졌다 하지 않고
양치가 다 끝난 후에 한 번만 물을 사용하는 것 🪥
function debounce(func, delay) {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), delay);
};
}
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('keyup', debounce(function() {
console.log('Search input value:', this.value);
}, 300));
// 사용자가 검색창에 키를 입력할 때마다 3초 후에야 콘솔에 메시지를 출
// 만약 사용자가 연속해서 입력하면 마지막 입력 후 3초가 지난 후에야 함수가 실행
이벤트 객체 (event object)
: 웹 페이지에서 발생하는 이벤트에 대한 정보를 담고 있는 객체
- 이벤트에 관한 상세한 정보를 넣은 다음, 핸들러에 인수 형태로 전달
- 이벤트 타입(click, keydown 등), 이벤트 발생 위치(마우스 위치 등), 이벤트 대상(클릭한 버튼 등) 등에 대한 정보를 담고 있는 객체
<input type="button" value="클릭해 주세요." id="elem">
<script>
elem.onclick = function(event) {
// 이벤트 타입과 요소, 클릭 이벤트가 발생한 좌표를 보여줌
alert(event.type + " 이벤트가 " + event.currentTarget + "에서 발생했습니다.");
alert("이벤트가 발생한 곳의 좌표는 " + event.clientX + ":" + event.clientY +"입니다.");
};
</script>
이벤트 종류
마우스 이벤트
- click
: 요소 위에서 마우스 왼쪽 버튼을 눌렀을 때(터치스크린이 있는 장치에선 탭 했을 때) 발생 - contextmenu
: 요소 위에서 마우스 오른쪽 버튼을 눌렀을 때 발생 - mouseover, mouseout
: 마우스 커서를 요소 위로 움직였을 때, 커서가 요소 밖으로 움직였을 때 발생 - mousedown, mouseup
: 요소 위에서 마우스 왼쪽 버튼을 누르고 있을 때, 마우스 버튼을 뗄 때 발생 - mousemove
: 마우스를 움직일 때 발생
폼 요소 이벤트
- submit
: 사용자가 <form>을 제출할 때 발생 - focus
: 사용자가 <input>과 같은 요소에 포커스 할 때 발생
키보드 이벤트
- keydown, keyup
: 사용자가 키보드 버튼을 누르거나 뗄 때 발생
문서 이벤트
- DOMContentLoaded
: HTML이 전부 로드 및 처리되어 DOM 생성이 완료되었을 때 발생
CSS 이벤트
- transitionend
: CSS 애니메이션이 종료되었을 때 발생