JavaScript_키보드와 스크롤 이벤트

cho·2023년 8월 20일

📖 키보드 이벤트

✏️KeyboardEvent.type

키보드 버튼을 누를 때는 keydown과 keypress 이벤트가 발생하고 키보드의 버튼을 떼는 순간에는 keyup 이벤트가 발생한다.

📚 keydown : 키보드 버튼을 누른 순간

하나의 키를 계속 누르고 있는 상황에서는 keypress는 한 번만 발생하고, keydown 이벤트만 연속적으로 발생한다. 심지어 출력이 가능한 키더라도 영어가 아닌 경우 반응하지 않는 문제도 있다.

📚 keypress : 키보드 버튼을 누른 순간

keypress는 알파벳이나 숫자, 혹은 스페이스바로 띄어쓰기를 한 것과 같이 출력값이 변하는 키에서만 이벤트가 발생하고, esc나 shift처럼 기능적인 역할을 하는 키보드에서는 이벤트가 발생하지 않는다.

📌주의사항

웹표준에서는 권장하지 않는 방법이기 때문에, 키를 누르는 순간 동작할 이벤트가 필요하다면 keydown 이벤트를 사용하는 것을 권장한다. 그러나 다음의 상황에는 keypress를 사용하기도 한다.

하나의 버튼에 하나의 값이 입력되는 영어와는 다르게, 한국어의 자음과 모음의 결합처럼 여러 버튼을 눌러서 하나의 입력 값을 만들 수 있는 언어들은 입력할 때 자세히 살펴보면, 화면에 입력중인 문자 바로 아래에 작은 밑줄이 나타나는 경우를 볼 수 있다.

만약 keyup, keydown 타입으로 이벤트 핸들러를 등록하고, 그 밑줄이 보이는 상황에서 enter나 esc, 혹은 방향키와 같은 키보드 버튼을 누를 경우 해당 버튼에 대한 이벤트가 2번 중복해서 반응하는 이슈가 있다. 왜냐하면 글자가 조합 중인지, 조합이 완료된 것인지 쉽게 파악하기 어렵기 때문이다. 그래서 특별한 상황에 따라서는 keypress가 필요할 수도 있다.

📚 keyup : 키보드 버튼을 눌렀다 뗀 순간

✏️ KeyboardEvent.key

이벤트가 발생한 버튼의 값
-> 키를 누를 때, 사용자가 어떤 값을 가진 키를 눌렀는지 알려주는 것이 key 프로퍼티이다.

✏️ KeyboardEvent.code

이벤트가 발생한 버튼의 키보드에서 물리적인 위치

-> 키보드 모양에서 강조되는 것처럼 사용자가 키보드에서 어떤 위치에 있는 키를 눌렀는지 알려주는 것이 code 프로퍼티이다. 그래서 대문자 A와 소문자 a를 눌렀을 때 key 값은 다르지만 code 값은 같은 경우도 있다. 혹은 왼쪽 shift와 오른쪽 shift를 눌렀을 때, key값은 같지만 code 값이 다른 경우도 있다.

📌 shiftKey, altKey, ctrlKey, metaKey

shiftKey, altKey, ctrlKey, metaKey 프로퍼티를 통해서 각 프로퍼티별로 키보드 이벤트가 발생하면 shift, alt, ctrl, meta (Windows or cmd) 키가 눌렸었는지 불린 형태로 파악할 수도 있다.

📌 enterKey

일반적으로 작은 노트북이나 키보드 오른쪽에 숫자판이 없는 짧은 텐키리스 키보드는 엔터키가 하나 밖에 없다.

그래서 두 프로퍼티 중 아무거나 사용해서 상관 없을 것 같지만 키보드 오른쪽에 숫자판이 있는 키보드의 경우에는 오른쪽 아랫부분에 enter 키가 하나 더 있다. 그 숫자판의 enter 키를 누르면 key 프로퍼티에는 'Enter' 가, code 프로퍼티에는 'numpadEnter' 라는 값이 담긴다.

만약 하나의 엔터키에만 프로그램이 동작하도록 하려면 code 프로퍼티로 두 enter 키를 구분하는 것이 좋고 두 엔터키 모두 동작하도록 하면 key 프로퍼티를 활용하는 것이 좋다.

*enterKey와 shift+enterkey의 기본동작은 줄바꿈이다. 기본 동작을 막기 위해서는 preventDefault 메소드를 활용하면 된다.

📖 input 태그 다루기

html 태그 중에서 특별히 input 태그는 다양한 type들을 가지고 있다. 일반적으로 글을 입력하는 text type, 입력값을 자동으로 가려주는 password type, 단순한 클릭이 가능한 button type, 클릭을 통해서 선택과 해지가 가능한 checkbox type이 있다. 이 밖에도 다양한 타입들이 있지만 이 정도가 평소에 많이 볼 수 있는 type들이다.

다른 태그들과 다르게 input 태그는 태그의 이름 그대로 입력의 역할을 하기 때문에 사용자의 키보드나 마우스 동작에 반응하는 특징이 있다. 클릭을 해보면 css로 강조를 지워주지 않는 이상 파란색 테두리로 강조된다. 이것이 사용자의 반응에 동작할 준비가 되었다는 뜻이며 이 상황을 포커스 되었다고 말한다.

✏️ 포커스 이벤트

📚 focusin : 요소에 포커스가 되었을 때

📚 focusout : 요소에 포커스가 빠져나갈 때

📚 focus : 요소에 포커스가 되었을 때 (버블링 X)

📚 blur : 요소에 포커스가 빠져나갈 때 (버블링 X)

form id를 가진 태그 자체는 일반 div 태그이기 때문에 focus가 가능하지 않고, focus와 blur이벤트는 버블링이 일어나지 않아 이벤트 위임을 활용하지 못한다. 그래서 요소에 접근하는 대상을 form id를 가진 요소가 아니라 좀 더 구체적이고 명확한 요소로 바꿔주면 동작할 수 있다.
여러 개의 input 태그가 있을 때 이벤트를 다루는 효율을 생각하면 focusin과 focusout을 활용하는게 좋지만 때로는 focus/blur를 사용해야 할 때도 있다.

✏️ 입력 이벤트

📚 input : 사용자가 입력을 할 때

말 그대로 어떤 값이 입력될 때 발생하기 때문에 esc나 shift 같은 입력과 관련 없는 key에는 이벤트가 발생하지 않는다는 차이가 있다.

📚 change : 요소의 값이 변했을 때

입력이 시작되기 전 값과 완료되었을 때 값 사이에 차이가 있을 때만 발생한다. 그래서 처음 input 태그에 focus를 두고 어떤 값을 입력할 때는 input 태그의 값이 입력 중인 상태로 평가되기 때문에 최종적으로 입력이 완료되었다는 암시를 주어야 한다.
일반적으로 focus가 빠져나갈 때 입력이 완료됐다고 판단해서 change 이벤트가 focusout 직전에 발생한다. focusout / blur 와 차이점은 실제로 값이 변했을 때 발생하기 때문에 그냥 focus만 왔다 갔다 하면 change 이벤트가 발생하지 않는다.
참고로 input 태그에서 값을 입력하다가 엔터 키를 누르는 것도 입력이 끝났다 라고 인식하기 때문에 focus를 잃지 않고 change 이벤트를 발생시킬 수도 있다.

📖 스크롤 이벤트

스크롤은 일반적으로는 웹문서의 크기가 브라우저의 창 크기보다 클 때 브라우저에 자연스럽게 나타난다. 그래서 스크롤 이벤트는 브라우저를 대변하는 윈도우 객체의 이벤트 핸들러를 등록하고 윈도우 객체의 프로퍼티와 함께 자주 활용된다.

scrollY라는 프로퍼티를 사용하면 스크롤된 특정한 위치를 기준으로 이벤트 핸들러가 동작하게 하거나 혹은 스크롤 방향 (위로 스크롤 중인지 / 아래로 스크롤 중인지) 을 기준으로 이벤트 핸들러가 동작하게끔 활용할 수 있다.

function printEvent(e) {
  console.log(e);
  console.log(window.scrollY);
}

window.addEventListener('scroll', printEvent);

📌 정리

KeyboardEvent.type설명
keydown키보드의 버튼을 누르는 순간
keypress키보드의 버튼을 누르는 순간 ('a', '5' 등 출력이 가능한 키에서만 동작하며, Shift, Esc 등의 키에는 반응하지 않는다.)
keyup키보드의 버튼을 눌렀다 떼는 순간

input 이벤트 타입설명
focusin요소에 포커스가 되는 순간
focusout요소에 포커스가 빠져나가는 순간
focus요소에 포커스가 되는 순간 (버블링이 일어나지 않음)
blur요소에 포커스가 빠져나가는 순간 (버블링이 일어나지 않음)
change입력된 값이 바뀌는 순간
input값이 입력되는 순간
select입력 양식의 하나가 선택되는 순간
submit폼을 전송하는 순간

0개의 댓글