안녕하세요.
이 공간은 제가 프론트엔드를 처음 접하며 배운 것을 주저리주저리 쓰는 공간입니다.
이번 내용은 javascript 8편입니다.

이벤트 활용

애플리케이션을 어떠한 형태로 구현할 수 있는지 이벤트 활용을 통해 알아봅시다!

이벤트 모델

표준 이벤트 모델은, 앞서 봤던 addEventListener()메소드입니다.

document.body.addEventListener('keyup', () => {
  // blahblah
}) 

모든 이벤트 모델의 이벤트 리스너 첫 번쨰 매개변수로 이벤트 객체를 받습니다.
이 이벤트 객체엔 이벤트 관련 정보가 들어있어요.
모든 이벤트를 살펴볼 수는 없기 때문에, 몇 가지 중요한 이벤트만 먼저 보겠습니다.

키보드 이벤트

keydown : 키보드에서 키가 눌릴 때 실행됩니다. 다만, 웹 브라우저에 따라서 CJK를 제대로 처리하지 못하는 경우가 왕왕 있습니다.
keypress : 특정 키가 입력되었을 때 실행됩니다. 다만, 웹 브라우저에 따라서 CJK를 제대로 처리하지 못하는 경우가 왕왕 있습니다.
keyup : 키보드에서 키가 떨어질 때 실행됩니다.

예시에서는 keyup이벤트를 사용해보겠습니다.

<body>
  <h1></h1>
  <textarea></textarea>
</body>
document.addEventListener('DOMContentLoaded', () => {
  const textarea = document.querySelector('textarea');
  const h1 = document.querySelector('h1');

  textarea.addEventListener('keyup', (event) => {
    const length = textarea.value.length;
    h1.textContent = `글자 수: ${length}`;
  })
})

결과는 어떻게 나올까요?

javascript는 정확하게 10글자가 나왔습니다.

그런데 "동해물과 백두산이"는 9글자로 나왔네요.
그 이유는, 띄어쓰기도 띄어쓰기 문자로 인식하기 때문입니다.

keyup, keydown, keypress 이벤트들은 각자 단점들이 존재합니다.
keyup 이벤트의 경우, 특정 값을 계속 누르고 있으면 글자 수를 세지 못합니다.
keypress 이벤트는 띄어쓰기, 줄바꿈 등 공백이 없다면 역시 글자 수를 세지 못합니다.

그래서 실제로 트위터는, 아래 코드와 같은 형식으로 글자 수를 세고 있습니다.
어떤 상황에서 어떤 언어를 입력해도 글자 수를 정상적으로 출력해줍니다.

document.addEventListener('DOMContentLoaded', () => {
  const textarea = document.querySelector('textarea')
  const h1 = document.querySelector('h1')
  let timerId

  textarea.addEventListener('focus', (event) => {
    timerId = setInterval(() => {
      const length = textarea.value.length
      h1.textContent = `글자 수: ${length}`
    }, 50)
  })
  textarea.addEventListener('blur', (event) => {
    clearInterval(timerId)
  })
})

focus 이벤트와 blur 이벤트를 활용했어요.
글자를 쓸 때 포커싱되면 setInterval() 메소드를 통해 50ms마다 입력양식 내부 글자를 확인하는 형태입니다.
반대로 글자를 다 쓴 후 포커싱이 해제되면 clearInterval() 메소드로 타이머를 헤재시키고 있네요.



이렇게 보니 결과가 같아 보이네요.



똑같이 ㅁ을 계속해 입력했을 때, 처음 본 코드를 사용했을 땐 글자 수가 0으로 나오지만, 아래의 코드를 사용하니 실시간으로 글자수가 집계됩니다.

키보드 키 코드 활용

code : 입력한 키
ckeCode : 입력한 키를 나타내는 숫자.
altKey : alt키를 눌렀는지의 여부를 확인해 boolean 값으로 반환.
ctrlKey : ctrl키를 눌렀는지의 여부 확인해 boolean 값으로 반환.
shiftKey : shift키를 눌렀는지의 여부 확인해 boolean 값으로 반환.

예시를 살펴보겠습니다.

<body>
  <h1></h1>
</body>
document.addEventListener('DOMContentLoaded', () => {
  const h1 = document.querySelector('h1')
  const print = (event) => {
    let output = ''
    output += `alt: ${event.altKey}<br>`
    output += `ctrl: ${event.ctrlKey}<br>`
    output += `shift: ${event.shiftKey}<br>`
    output += `code: ${typeof(event.code) !== 'undefined' ?
      event.code: event.keyCode}<br>`
    h1.innerHTML = output
  }

  document/addEventListener('keydown', print)
  document/addEventListener('keyup', print)
})

output을 통해 각각 이벤트가 발생하면 boolean 값을 반환하고 있습니다.
그 아래엔 envent.code가 있을 시 event.code를 출력하고,
만약 undefined라면 code.Keycode를 출력합니다.

저장하고 키보드를 눌러볼게요.

ctrl, alt, shift가 눌렸는지 boolean값으로 반환하고,
최종적으로 눌린 키가 어떤 키인지가 반환되네요.
이게 왜 필요할까요?

실제 페이스북에서 alt + 숫자를 입력할 경우 특정 페이지로 이동합니다.
이러한 단축기 구현을 가능하게 해주는 게 바로 키 코드인거죠.

keyCode 속성을 활용하는 예시도 보겠습니다.

<body>
  <h1></h1>
</body>
document.addEventListener('DOMContentLoaded', () => {
  const star = document.querySelector('h1')
  star.style.position = 'absolute'
  
  let [x, y] = [0, 0]
  const block = 20
  const print = () => {
    star.style.left = `${x * block}px`
    star.style.top = `${x * block}px`
  }
  print()

  const [left, up, right, down] = [37, 38, 39, 40]
  document.body.addEventListener('keydown', (event) => {
    switch (event.keyCode) {
      case left:
        x -= 1
        break
      case up:
        y -= 1
        break
      case right:
        x += 1
        break
      case down:
        y += 1
        break
    }
    print()
  })
})

화살표를 움직이면, 별이 그 방향으로 움직입니다.

profile
수제 에러코드 전문점 / 불량코드 원조 맛집

0개의 댓글