이벤트
이벤트 드리븐 프로그래밍
- 이벤트 핸들러 : 이벤트가 발생됐을때 호출할 함수
- 이벤트 핸들러 등록 : 이벤트가 발생했을때 브라우저에게 이벤트 핸들러의 호출을 위임
이벤트 타입
마우스
이벤트 타입 | 이벤트 발생 시점 |
---|---|
click | 마우스 버튼을 클릭했을 때 |
dblclick | 마우스 버튼을 더블 클릭했을 때 |
mousedown | 마우스 버튼을 눌렀을 때 |
mouseup | 누르고 있던 마우스 버튼을 놓았을 때 |
mousemove | 마우스 커서를 움직였을 때 |
mouseenter | 마우스 커서를 HTML 요소 안으로 이동했을 때(버블링 2되지 않는다) |
mouseover | 마우스 커서를 HTML 요소 안으로 이동했을 때(버블링된다) |
mouseleave | 마우스 커서를 HTML 요소 밖으로 이동했을 때(버블링되지 않는다) |
mouseout | 마우스 커서를 HTML 요소 밖으로 이동했을 때(버블링된다) |
키보드
이벤트 타입 | 이벤트 발생 시점 |
---|---|
keydown | 모든 키를 눌렀을 때 발생한다. ※ control, option, shift, tab, delete, enter, 방향 키와 문자, 숫자, 특수 문자 키를 눌렀을 때 발생한다. 단, 문자, 숫자, 특수 문자, enter 키를 눌렀을 때는 연속적으로 발생하지만 그 외의 키를 눌렸을 때는 한 번만 발생한다. |
keypress | 문자 키를 눌렀을 때 연속적으로 발생한다. ※ control, option, shift, tab, delete, 방향 키 등을 눌렀을 때는 발생하지 않고 문자, 숫자, 특수 문자, enter키를 눌렀을 때만 발생한다. 폐지(deprecated)되었으므로 사용하지 않을 것을 권장한다. |
keyup | 누르고 있던 키를 놓았을 때 한 번만 발생한다. ※ keydown 이벤트와 마찬가지로 control, option, shift, tab, delete, enter, 방향 키와 문자, 숫자, 특수 문자 키를 놓았을 때 발생한다. |
포커스
이벤트 타입 | 이벤트 발생 시점 |
---|---|
focus | HTML 요소가 포커스를 받았을 때(버블링되지 않는다) |
blur | HTML 요소가 포커스를 잃었을 때(버블링되지 않는다) |
focusin | HTML 요소가 포커스를 받았을 때(버블링된다) |
focusout | HTML 요소가 포커스를 잃었을 때(버블링된다) |
focusin, focusout 이벤트 핸들러를 이벤트 핸들러 프로퍼티 방식으로 등록하면 크롬, 사파리에서 정상 동작하지 않는다. focusin, focusout 이벤트 핸들러는 addEventListener 메서드 방식을 사용해 등록해야 한다.
폼
이벤트 타입 | 이벤트 발생 시점 |
---|---|
submit | 1. form 요소 내의 input(text, checkbox, radio), select 입력 필드(textarea 제외)에서 엔터키를 눌렀을 때 2. form 요소 내의 submit 버튼( |
reset | form 요소 내의 reset 버튼을 클릭했을 때(최근에는 사용 안 함) |
값
이벤트 타입 | 이벤트 발생 시점 |
---|---|
input | input(text, checkbox, radio), select, textarea 요소의 값이 입력되었을 때 |
change | input(text, checkbox, radio), select, textarea 요소의 값이 변경되었을 때 ※ change 이벤트는 input 이벤트와는 달리 HTML 요소가 포커스를 잃었을 때 사용자 입력이 종료되었다고 인식하여 발생한다. 즉, 사용자가 입력을 하고 있을 때는 input 이벤트가 발생하고 사용자 입력이 종료되어 값이 변경되면 change 이벤트가 발생한다. |
readystatechange | HTML 문서의 로드와 파싱 상태를 나타내는 document.readyState 프로퍼티 값(‘loading’, ‘interactive’, ‘complete’)이 변경될 때 |
DOM 뮤테이션
이벤트 타입 | 이벤트 발생 시점 |
---|---|
DOMContentLoaded | HTML 문서의 로드와 파싱이 완료되어 DOM 생성이 완료되었을 때 |
뷰 이벤트
이벤트 타입 | 이벤트 발생 시점 |
---|---|
resize | 브라우저 윈도우(window)의 크기를 리사이즈할 때 연속적으로 발생한다. ※ 오직 window 객체에서만 발생한다. |
scroll | 웹페이지(document) 또는 HTML 요소를 스크롤할 때 연속적으로 발생한다. |
리소스 이벤트
이벤트 타입 | 이벤트 발생 시점 |
---|---|
load | DOMContentLoaded 이벤트가 발생한 이후, 모든 리소스(이미지, 폰트 등)의 로딩이 완료되었을 때(주로 window 객체에서 발생) |
unload | 리소스가 언로드될 때(주로 새로운 웹페이지를 요청한 경우) |
abort | 리소스 로딩이 중단되었을 때 |
error | 리소스 로딩이 실패했을 때 |
기타 이벤트
책에서 생략된 부분 많음.
(touch, composition, mediastream, animation 등등)
https://developer.mozilla.org/ko/docs/Web/API/Event
이벤트 핸들러 등록
이벤트 핸들러 어트리뷰트 방식
이벤트 핸들러 어트리뷰트 값은 사실 암묵적으로 생성될 이벤트 핸들러의 함수 몸체를 의미한다.(자체적으로 이벤트 핸들러 프로퍼티에 할당)
<button onclick="handleClick">Click me!</button>
<!-- Angular -->
<button (click)="handleClick($event)">Save</button>
{ /* React */ }
<button onClick={handleClick}>Save</button>
<!-- Svelte -->
<button on:click={handleClick}>Save</button>
<!-- Vue.js -->
<button v-on:click="handleClick($event)">Save</button>
이벤트 핸들러 프로퍼티 방식
//타깃, 타입, 핸들러
$button.onclick = function () {
console.log('button click');
};
addEventListener 메서드 방식
target.addEventListener(type, handler, useCapture);
$button.addEventListener('click', function () {
console.log('button click');
});
이벤트 핸들러 제거
$button.removeEventListener('click', handleClick);
//이벤트 핸들러 프로퍼티 방식으로 등록한 경우
$button.onclick = null;
이벤트 객체
이벤트 발생시 이벤트 객체가 동적으로 생성되고 이벤트 핸들러의 첫번째 인수로 전달됨.
function showCoords(e) {
$msg.textContent = `clientX: ${e.clientX}, clientY: ${e.clientY}`;
}
// Event 생성자 함수를 호출하여 foo 이벤트 타입의 Event 객체를 생성한다.
let e = new Event('foo');
console.log(e);
// Event {isTrusted: false, type: "foo", target: null, ...}
console.log(e.type); // "foo"
console.log(e instanceof Event); // true
console.log(e instanceof Object); // true
// FocusEvent 생성자 함수를 호출하여 focus 이벤트 타입의 FocusEvent 객체를 생성한다.
e = new FocusEvent('focus');
console.log(e);
// FocusEvent {isTrusted: false, relatedTarget: null, view: null, ...}
// MouseEvent 생성자 함수를 호출하여 click 이벤트 타입의 MouseEvent 객체를 생성한다.
e = new MouseEvent('click');
console.log(e);
// MouseEvent {isTrusted: false, screenX: 0, screenY: 0, clientX: 0, ... }
// KeyboardEvent 생성자 함수를 호출하여 keyup 이벤트 타입의 KeyboardEvent 객체를 생성한다.
e = new KeyboardEvent('keyup');
console.log(e);
// KeyboardEvent {isTrusted: false, key: "", code: "", ctrlKey: false, ...}
// InputEvent 생성자 함수를 호출하여 change 이벤트 타입의 InputEvent 객체를 생성한다.
e = new InputEvent('change');
console.log(e);
// InputEvent {isTrusted: false, data: null, inputType: "", ...}
프로토타입 체인으로 상위 이벤트로 연결됨.
ex) click -> MouseEvent -> UIEvent -> Event
공통 프로퍼티 | 설명 타입 |
---|---|
type | 이벤트 타입 |
target | 이벤트를 발생시킨 DOM 요소 |
currentTarget | 이벤트 핸들러가 바인딩된 DOM 요소 |
eventPhase | 이벤트 전파 단계 0: 이벤트 없음, 1: 캡처링 단계, 2: 타깃 단계, 3: 버블링 단계 |
bubbles | 이벤트를 버블링으로 전파하는지 여부. 다음 이벤트는 bubbles: false로 버블링하지 않는다. ■ 포커스 이벤트 focus/blur ■ 리소스 이벤트 load/unload/abort/error ■ 마우스 이벤트 mouseenter/mouseleave |
cancelable | preventDefault 메서드를 호출하여 이벤트의 기본 동작을 취소할 수 있는지 여부. 다음 이벤트는 cancelable: false로 취소할 수 없다. ■ 포커스 이벤트 focus/blur ■ 리소스 이벤트 load/unload/abort/error ■ 마우스 이벤트 dblclick/mouseenter/mouseleave |
defaultPrevented | preventDefault 메서드를 호출하여 이벤트를 취소했는지 여부 |
isTrusted | 사용자의 행위에 의해 발생한 이벤트인지 여부. 예를 들어, click 메서드 또는 dispatchEvent 메서드를 통해 인위적으로 발생시킨 이벤트인 경우 isTrusted는 false다. |
timeStamp | 이벤트가 발생한 시각(1970/01/01/00:00:0부터 경과한 밀리초) |
이벤트 전파
- 캡처링 단계 – 이벤트가 하위 요소로 전파되는 단계
- 타깃 단계 – 이벤트가 실제 타깃 요소에 전달되는 단계
- 버블링 단계 – 이벤트가 상위 요소로 전파되는 단계
이벤트 위임
이벤트에 반응이 필요한 DOM 요소(실제 이벤트가 동작하는 el)에 한정하여 이벤트 핸들러가 실행되도록 이벤트 타깃을 검사할 필요가 있다.
DOM 요소의 기본 동작 조작
//기본동작 중단
e.preventDefault();
// 이벤트 전파 중단
e.stopPropagation();
이벤트 핸들러 내부의 this
이벤트 핸들러 어트리뷰트 방식
전역 객체 window를 가르킴.
단, 인수로 전달 받았을때는 이벤트를 바인딩한 DOM 요소
이벤트 핸들러 프로퍼티 방식과 addEventListener 메서드 방식
이벤트를 바인딩한 DOM 요소
화살표 함수인 경우 상위 스코프의 this
클래스 사용시 bind 메서드로 class의 this 전달. 또는 화살표 함수 사용.
이벤트 핸들러에 인수 전달
책 내용 잘못됨. addEventListner도 가능.
obj.addEventListener('click', (event)=>
callback(event, '인수');
);
커스텀 이벤트
<!DOCTYPE html>
<html>
<body>
<button class="btn">Click me</button>
<script>
const $button = document.querySelector('.btn');
// 버튼 요소에 foo 커스텀 이벤트 핸들러를 등록
// 커스텀 이벤트를 디스패치하기 이전에 이벤트 핸들러를 등록해야 한다.
$button.addEventListener('foo', e => {
// e.detail에는 CustomEvent 함수의 두 번째 인수로 전달한 정보가 담겨 있다.
alert(e.detail.message);
});
// CustomEvent 생성자 함수로 foo 이벤트 타입의 커스텀 이벤트 객체를 생성
const customEvent = new CustomEvent('foo', {
detail: { message: 'Hello' } // 이벤트와 함께 전달하고 싶은 정보
});
// 커스텀 이벤트 디스패치
$button.dispatchEvent(customEvent);
</script>
</body>
'공부공부 > JS 딥다이브' 카테고리의 다른 글
[js 딥다이브] 42장 비동기 프로그래밍 (0) | 2024.02.18 |
---|---|
[js 딥다이브] 41장 타이머 (0) | 2024.02.18 |
[js 딥다이브] 39장 DOM (0) | 2024.02.18 |
[js 딥다이브] 38장 브라우저의 렌더링 과정 (0) | 2024.02.18 |
[js 딥다이브] 37장 Set과 Map (0) | 2024.02.18 |