키보드 이벤트 핸들링

키보드 이벤트 핸들링 (Keyboard Event Handling)

접근성을 고려해서 마우스 이벤트 뿐만 아니라, 키보드 이벤트도 같이 공부해야 한다.

태블릿 PC같은 경우는 터치 이벤트 환경이기 때문에 마우스 이벤트는 발생하지 않는다.

브라우저 호환성 → 기본적으로 모든 브라우저에서 호환이 가능하다.(event.keyCode 포함)

단, 다른 기능들 중 어떤 기능은 모든 브라우저에서 호환되지 않는다.

  • 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 = 오른쪽을 보며 이동

실습에 사용된 steps()에 대해 공부해 보고 싶다면 링크에 들어가서 예제 확인하기

처음에 작성한 코드

이벤트

// 문서 객체 참조 
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?