키보드 이벤트 핸들링
키보드 이벤트 핸들링 (Keyboard Event Handling)
접근성을 고려해서 마우스 이벤트 뿐만 아니라, 키보드 이벤트도 같이 공부해야 한다.
event.keyCode
값은 사람이 인식하기에 쉽지 않다.이벤트 속성:
keydown
,keypress
,keyup
/input
(HTML5, 태블릿 PC 생각하기)이벤트 객체 (Event Object)
이벤트 발생 순서
keydown ➔ keypress ➔ keyup
keydown, keypress : 거의 동시에 이루어진다. 또한 사용자가 키를 누르자마자 발생하게 된다.
keypress : 화살표 키는 인지 하지 못한다.
keyup : 사용자가 누르고 있던 키를 뗄 때 한 번 발생하게 된다.
특징
키가 처음 눌려지면 keydown 이벤트가 발생한다.
(영문, 숫자, space, enter(return), 한글, tab, caps lock, shift, ctrl, alt(option), command(MAC), arrow(화살표), F1~12) → 대부분의 키가 인식 가능하다.
keydown 이벤트 이후, keypress 이벤트가 발생한다.
(영문, 숫자, space, enter(return)) / keydown 이벤트와 다르게 제한 적으로 이벤트를 감지한다.
키를 놓으면 keyup 이벤트가 발생한다.
(tab, caps lock 발생 X) / keydown 처럼 대부분의 이벤트를 감지한다.
키보드 인터랙션 테스트
keydown, keypress, keyup, input 이벤트 간 차이를 확인 할 수 있다.
실습
목표
화살표 키 up을 누르면, boy 캐릭터가 점프해야 한다.
점프 후에는 다시 서 있는 boy 캐릭터로 변경되어야 한다.
화살표 키 left, right를 누르면 boy 캐릭터가 누른 방향으로 이동한다.
arrow-top = 점프 / space
arrow-left = 왼쪽을 보며 이동
arrow-right = 오른쪽을 보며 이동
처음에 작성한 코드
이벤트
// 문서 객체 참조
var boy = el('.boy');
// 조건이 많아지기 때문에 switch 문을 사용
window.addEventListener('keydown', function(e) {
// console.log(e.type, ' = ', e.keyCode, ' | ', e.code, ' | ', e.key);
switch(e.keyCode) {
case 38: // up
case 32: // space
jump(); break;
case 37: // arrow right
moveLeft(); break;
case 39: // arrow right
moveRight();
}
})
키코드에 각각의 해당되는 인터랙션 함수를 적용해야 하기때문에 조건이 많아진다. 그래서 if문이 아닌 switch문 사용
키보드의 코드 등 정보를 확인하기 위해 아래 구문 사용 하여 콘솔 패널에서 확인
console.log(e.type, ' = ', e.keyCode, ' | ', e.code, ' | ', e.key);
인터랙션을 위한 함수
jump()
// jump 클래스 추가 후 여전히 요소에 클래스가 남아있는 이슈를 해결
boy.addEventListener('animationend', stand)
function stand() {
boy.classList.remove('jump');
}
function jump() {
boy.classList.add('jump');
}
jump()
함수를 실행하고나서 .jump
클래스가 여전히 요소에 남아 있는 문제를 해결하기 위해 .remove()
메서드를 실행하는 stand()
함수를 생성
moveLeft(), moveRight()
function moveLeft() {
// 함수가 실행 됐을 때 애니메이션이 마치 움직이게(이동하기)하기 위해 translateX 값을 가져온다.
var disX = window.parseInt(boy.style.transform.replace('translateX(', ''), 10) || 0;
console.log(disX);
boy.style.transform = 'translateX(' + (disX -= 30) + 'px) rotateY(180deg)';
}
function moveRight() {
var disX = window.parseInt(boy.style.transform.replace('translateX(', ''), 10) || 0;
console.log(disX);
boy.style.transform = 'translateX(' + (disX += 30) + 'px) rotateY(0deg)';
}
.style
메서드를 사용해서 화살표 키를 눌렀을 때 캐릭터의 방향이 바뀌도록 설정한다. →rotateY()
캐릭터를 움직이게 하기 위해
translateX()
속성을 사용했으나 "이동"이 아닌 "위치"만 변화한다.캐릭터가 좌/우로 이동하도록 하기 위해 키보드를 누를 때 마다
translateX()
의 값이 커지거나 작아지게 해야한다.console.log(boy.style.transform)
로 값을 확인하고 초기값(0)으로 만들기 위해 논리 연산자를 사용한다. →var disX = boy.style.transform || 0
'translateX(-30px) rotateY(0deg)'
문자값에서-30
숫자만을 빼오기 위해replace()
메서드를 사용해서 숫자 이전까지 문자열을 잘라주고window.parseInt()
를 사용해서disX
변수에translateX()
의 값인-30
을 할당하게 한다.복합 대입 연산자를 사용해서 화살표 키를 누를 때마다 -30이 더해져서 캐릭터가 화면에서 이동하는 것처럼 보이게 한다. →
disX -= 30
마지막으로 해당 속성에 값이 들어가도록 문자열 접합을 해준다. →
'translateX(' + (disX -= 30) + 'px) rotateY(180deg)'
코드 리팩토링
getDistanceX()
함수 만들어서 중복되는 구문 헬퍼 함수로 만든다.유지 보수를 고려해서
distanceX
(캐릭터 이동 거리 설정) 변수 만든다.
var boy = el('.boy');
var distanceX = 40;
window.addEventListener('keydown', function(e) {
switch(e.keyCode) {
case 38: // up
case 32: // space
jump(); break;
case 37: // arrow right
moveLeft(); break;
case 39: // arrow right
moveRight();
}
})
boy.addEventListener('animationend', stand)
function stand() {
boy.classList.remove('jump');
}
function jump() {
boy.classList.add('jump');
}
function getDistanceX() {
return window.parseInt(boy.style.transform.replace('translateX(', ''), 10) || 0;
}
function moveLeft() {
var disX = getDistanceX() - distanceX
boy.style.transform = 'translateX(' + disX + 'px) rotateY(180deg)';
}
function moveRight() {
var disX = getDistanceX() + distanceX
boy.style.transform = 'translateX(' + disX + 'px) rotateY(0deg)';
}
구형 / 신형 이벤트 모델
해당 실습 자료의 소년 캐릭터에는
<input>
요소가 포함되어 있지 않기 때문에window
또는document
에 이벤트를 적용해 주어야 한다.function(event)
함수의 인자로 이벤트를 받는다.매개변수의 값은
event
,evt
,ev
,e
중 하나의 이름으로 많이 쓴다.
// 구형
window.onkeydown = function(){ };
// 신형
// 내부에 이벤트 핸들러 구문 작성
window.addEventListener('keydown', function(e){
console.log(e.type) // "keydown"
});
// e : 이벤트 객체이기 때문에 속성을 가진다.
// .type : 'keydown'의 값을 반환한다.
Last updated
Was this helpful?