이벤트 모델
이벤트를 연결하는 방법
표준 이벤트 모델
addEventListener(type, listener)
addEventListener(type, listener, options)
addEventListener(type, listener, useCapture)
type : 이벤트 유형
listener : 지정할 이벤트를 받을 객체
options
- capture
- 이벤트 대상의 DOM 트리 하위에 위치한 자손 EventTarget으로 이벤트가 전달되기 전에
이 listener가 먼저 동작해야함을 나타내는 옵션 - default : false
- 이벤트 대상의 DOM 트리 하위에 위치한 자손 EventTarget으로 이벤트가 전달되기 전에
- once
- listener가 최대 한 번만 동작해야 함을 나타낸다
- true라면 listener가 동작하고 스스로를 제거한다
- passive
- true일 경우 preventDefault()를 절대 호출하지 않는다
- signal
- AbortSignal
- 지정한 AbortSignal 객체의 abort() 메서드를 호출하면 listener가 제거된다
useCapture
- 이벤트 대상의 DOM 트리 하위에 위치한 자손 EventTarget으로 이벤트가 전달되기 전에
이 listener가 먼저 동작해야함을 나타낸다 - 이벤트 버블링과 캡처링은 조상-자손 관계를 가진 두 개의 요소가 같은 이벤트 유형의 listener를 가지고 있을 때
두 요소에 이벤트가 전파되는 방법을 말한다. - 기본값 false (버블링 : bottom-top)
반환값 : undefined
addEventListener에 지정하는 listener는 콜백함수거나 handleEvent() 메서드를 포함하는 객체다.
콜백함수는 매개변수로 event기반의 객체만 받는다.
<table id="outside">
<tr><td id="t1">one</td></tr>
<tr><td id="t2">two</td></tr>
</table>
function modifyText() {
const t2 = document.getElementById("t2");
if (t2.firstChild.nodeValue == "three") {
t2.firstChild.nodeValue = "two";
} else {
t2.firstChild.nodeValue = "three";
}
}
// 표에 이벤트 수신기 추가
const el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);
간단하게 테이블에 이벤트 리스너를 부착해본 코드
false는 버블링을 의미한다
표를 아무데나 클릭하면 클릭 이벤트가 버블링 방식으로 전파되어, 이벤트 리스너를 만나게 되면서 t2의 글이 변한다
중단 가능한 수신기 추가
// 표에 중단 가능한 수신기 추가
const controller = new AbortController();
const el = document.getElementById("outside");
el.addEventListener("click", modifyText, { signal: controller.signal } );
// t2의 콘텐츠를 바꾸는 함수
function modifyText() {
const t2 = document.getElementById("t2");
if (t2.firstChild.nodeValue == "three") {
t2.firstChild.nodeValue = "two";
} else {
t2.firstChild.nodeValue = "three";
controller.abort(); // 값이 "three"가 되면 수신기 제거
}
}
AbortSignal 인터페이스는 DOM 요청과 통신한다. 부모 인터페이스 EventTarget으로 프로퍼티를 상속받는다.
그리고 필요한 경우 AbortController 객체를 통해 취소할 수 있게 해주는 신호 객체이다.
signal 프로퍼티는 DOM요청과 통신하거나 취소하는데 사용하는 AbortSignal 객체 인터페이스를 반환한다.
AbortSignal.aborted 프로퍼티는 신호가 요청이 취소되었는지(true) 아닌지(false)를 나타낸다
abort 메서드를 통해 DOM요청이 완료되기 전에 취소할 수 있다.
옵션 객체 사용
const capture = {
capture : true
};
const noneCapture = {
capture : false
};
const once = {
once : true
};
const noneOnce = {
once : false
};
const passive = {
passive : true
};
const nonePassive = {
passive : false
};
outer.addEventListener('click', onceHandler, once);
outer.addEventListener('click', noneOnceHandler, noneOnce);
middle.addEventListener('click', captureHandler, capture);
middle.addEventListener('click', noneCaptureHandler, noneCapture);
inner1.addEventListener('click', passiveHandler, passive);
inner2.addEventListener('click', nonePassiveHandler, nonePassive);
코드 출처 : https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener
인라인 이벤트 모델
<body>
<h1 onclick="listener(event)">1</h1>
<script>
const listener = (evt) => {
console.log(1)
}
</script>
</body>
위 처럼 HTML요소의 onEventName 속성에 자바스크립트 코드를 넣는 것이다.
이벤트 객체
모든 이벤트 모델의 이벤트 리스너는 첫 번째 매개변수로 이벤트 객체를 받는다.
이벤트 객체에는 이벤트와 관련된 정보가 들어있다
Event.target
이벤트 객체의 target 프로퍼티는 이벤트가 처음에 발생한 대상을 가리킨다
Event.currentTarget
이벤트 객체의 currentTarget 프로퍼티는 이벤트의 현재 대상이다.
이벤트 전파 과정 중에 이벤트를 받고 있는 객체를 가리킨다.
이벤트 리스너를 함수 리터럴 형태로 선언한 경우에 this를 이용하여 현재 이벤트 리스너가 등록된 HTML 요소를 선택할 수 있다.
<script>
const listener = function (e){
const length = this.value.length;
const h1 = document.querySelector('h1')
h1.textContent = `글자 수: ${length}`
}
document.addEventListener('DOMContentLoaded',() => {
const textarea = document.querySelector('textarea')
const h1 = document.querySelector('h1')
textarea.addEventListener('keypress', listener)})
</script>
Event.bubbles
이벤트가 DOM을 타고 버블링 되는지 나타내는 불리언이다
Event.composedPath()
이벤트의 경로(리스너가 발동할 객체들의 배열)를 반환한다.
Event.preventDefault()
취소 가능한 이벤트를 취소한다
stopPropagation()을 호출하기 전까지는 전파된다
Event.stopPropagation()
현재 이벤트가 캡처링/버블링 단계에서 더 이상 전파되지 않도록 방지한다.
전파를 방지해도 이벤트의 기본 동작은 실행된다.
즉, stopPropagation이 링크나 버튼의 클릭을 막는 것이 아니다.
기본 동작을 방지하려면 preventDefault를 사용해야 한다
Event.stopImmediatePropagation()
동일한 이벤트에 대한 나머지 리스너가 발동하지 못하도록 방지한다.
같은 이벤트 유형에 대한 여러 리스너를 하나의 요소에 부착한 경우, 리스너의 호출 순서는 부착 순서와 동일하다
리스너들 중 하나에서 이 메서드를 호출하면 나머지 리스너들은 호출되지 않는다
버블링 캡처링
부모 요소를 가지고 있는 요소에서 이벤트가 발생되면 캡처링이나 버블링 단계가 실행된다
캡처링
<html>부터 시작해서 실제로 선택된 요소까지 단계적으로 내려가면서
등록된 이벤트 핸들러가 있는지 확인하기 위해 반복적으로 검사하고, 있다면 실행한다
버블링
선택된 요소부터 <html>요소까지 단계적으로 올라가면서
등록된 이벤트 핸들러가 있는지 확인하기 위해 반복적으로 검사하고, 있다면 실행한다
이로 인해 문제가 발생할 수 있는데 그래서 이벤트 전파를 막을려면 stopPropagation 을 이용해야 한다
키보드 이벤트
KeyboardEvent 객체는 키보드와 사용자의 상호 작용을 나타낸다.
위 3개의 이벤트 타입은 키보드에서 어떤 행동이 일어났는지 식별한다
프로퍼티
KeyboardEvent.altKey
키 이벤트가 일어났을 때 alt키가 활성화 되어 있으면 true를 반환한다.
KeyboardEvent.ctrlKey
키 이벤트가 일어났을 때 ctrl키가 활성화 되어 있으면 true를 반환한다.
KeyboardEvent.shiftKey
키 이벤트가 일어났을 때 shift키가 활성화 되어 있으면 true를 반환한다.
KeyboardEvent.code
이벤트가 일어난 키의 물리적인 키코드 값을 문자열로 반환한다
키보드 레이아웃을 무시해서, 장치에 따라 다른 값을 리턴하는 경우가 생긴다
KeyboardEvent.keyCode
이벤트가 일어난 키의 물리적인 키코드 값을 문자열로 반환한다
KeyboardEvent.location
키보드나 기타 입력 장치의 키의 위치를 나타내는 Number를 반환한다.
메서드
KeyboardEvent.getModifierState()
이벤트가 발생했을 때 Alt, Shift, Ctrl, Meta 등의 보조 키가 눌렸는지 나타내는 불리언을 반환
이벤트
keyup
키보드에서 키가 떨어질 때 실행된다.
keydown
키보드에서 키가 눌릴 때 실행된다. 키보드를 누르고 있어도, 입력될 때도 실행된다
keypress
키가 입력됐을 때 실행된다.
mdn 에서 이 이벤트는 매우 장치 의존적이라서 더이상 사용하면 안된다고 한다.
키가 처음 눌리면 keydown 이벤트가 전송되고, 그 키가 보조 키가 아니라면 keypress 이벤트가 전송된다
그리고 키를 떼면 keyup 이벤트가 전송된다
키를 누르고 있는 동안에는 이벤트가 자동으로 반복된다.
다음과 같은 순서로 이벤트가 전송된다
keydown → keypress → keydown → keypress → keydown → keypress → ... → keyup
키를 누르는 동안 전송되는 이벤트를 기록한 코드를 작성했을 때 위와 같이 나타난다
그러나 Ubuntu 등의 일부 환경에서는 반복 순서가 다른 경우도 있다고 한다
글자 입력 양식 이벤트
사용자로부터 어떤 입력을 받을 때 사용하는 요소를 form이라고 한다
HTML에서는 input, textarea, button, select 등이 모두 입력 양식이다
change 이벤트
사용자가 input, select, textarea, button 태그 등의 요소의 값이 변경할 떄 발생한다
change 이벤트는 값이 바뀐 요소와 값을 바꾼 방법에 따라 발생하는 시점이 달라진다
- <input type="checkbox">
- 요소를 클릭하거나 키보드를 사용해서 체크하거나 해제할 때
- <input type="radio">
- 요소가 체크될 때 (해제될 때는 발생안함)
- 사용자가 변경사항을 직접 반영할 때
- <select> 드롭다운에서 값을 클릭
- <input type="date"> 달력에서 날짜 선택
- <input type="file"> 파일 선택 창에서 파일을 선택할 때
- <textarea>, <input>의 text, search, url, tel, email, password 타입
- 사용자 상호작용이 값 선택이 아니라 타이핑인 요소태그의 값이 바뀐 뒤 포커스를 상실했을 때
드롭다운 목록은 기본적으로 select 태그로 구현한다
select 요소는 options 프로퍼티를 갖는다.
select.options[idx] 식의 인덱싱도 가능하다.
select 태그에 multiple 속성을 부여하면 ctrl이나 shift키를 누르고 여러 항목을 선택할 수 있다.
option에는 selected 프로퍼티가 있다. 선택된 요소라면 true를 반환한다.
체크박스의 체크 상태를 확인할 때는 입력 양식의 checked 프로퍼티를 사용한다
체크상태라면 true를 반환한다.
라디오 버튼도 마찬가지로 checked 프로퍼티가 존재한다
참고 : mdn
'front-end > JavaScript' 카테고리의 다른 글
[JavaScript] Array.prototype.forEach , map, filter (0) | 2023.04.20 |
---|---|
[JavaScript] 콜백함수, 화살표 함수 (0) | 2023.04.20 |
[JavaScript] 생성자 함수 (0) | 2023.04.12 |
[JavaScript] 객체 리터럴 (0) | 2023.04.10 |
[JavaScript] 타입 변환 (0) | 2023.04.08 |