안녕하세요.
이 공간은 제가 프론트엔드를 처음 접하며 배운 것을 주저리주저리 쓰는 공간입니다.
이번 내용은 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()
})
})
화살표를 움직이면, 별이 그 방향으로 움직입니다.
