1 분 소요

Keydown Event 중첩 안됨

CODE

HTML

<div id="hero" class="front" style="left: 326px"></div>

CSS

#hero {
    position: relative;
    width: 48px;
    height: 64px;
    top: 70%;
}

Javascript

const heroElement = document.getElementById('hero');

const heroLeft = heroElement.style.left;

const heroLeftWithoutPx = Number(heroLeft.split('px')[0]);

document.addEventListener('keydown', function(e) {
    if(e.keyCode === 37) {
        heroElement.style.left = heroLeftWithoutPx - 10 + 'px'
        
    } else if(e.keyCode === 39) {
        heroElement.style.left = heroLeftWithoutPx + 10 + 'px';
    }
})

현상

key를 눌렀을 때 캐릭터인 heroleft값의 변화가 중첩되어 이동되어야 하지만, 무슨 이유인지 left값이 계속 초기화되어 위치가 한 번 밖에 변화되지 않는다.
밑에 addEventListener부분에 console.log로 출력되는 결과를 확인해보자.

document.addEventListener('keydown', function(e) {
    if(e.keyCode === 37) {
        heroElement.style.left = heroLeftWithoutPx - 10 + 'px'
        console.log('왼쪽' + (heroLeftWithoutPx - 10) + 'px');
        console.log(heroLeft);
        
    } else if(e.keyCode === 39) {
        heroElement.style.left = heroLeftWithoutPx + 10 + 'px';
        console.log('오른쪽' + (heroLeftWithoutPx + 10) + 'px')
        console.log(heroLeft);
    }
})


(heroleft값은 326px이 기본이다!)
왼쪽 방향키를 여러번 눌렀지만, heroleft값은 전혀 변하지 않는다.

오른쪽도 마찬가지이다.

이러니 방향키를 아무리 눌러도 캐릭터는 좌로 10px, 우로 10px만 움직이는 현상이 발생한다.

원인

이러한 현상이 발생한 원인은 addEventListener로 인해 변경된 값이 heroleftheroElement.style.left에 반영되지 않기 때문이라고 생각했다.
그럼 왜 바뀌지 않을까?? const는 상수라 안되는건가 싶어 let으로도 바꿔봤지만, 만약 이게 문제였다면 실행하자마자 에러가 발생했을 것이고, 결과도 동일한 현상이 발생했다.
그렇게 코드를 뚫어져라 보다가 왜 left의 변경된 값이 반영되지 않는지 깨달았다.

해결

의외로 간단한 문제였다.. addEventListener에서 keydown이벤트로 인해 조건문 함수가 실행되어 left값이 변한다. 그러나 heroElement의 style을 선언하는 선언문들

const heroLeft = heroElement.style.left;

const heroLeftWithoutPx = Number(heroLeft.split('px')[0]);

이 선언문들이 함수 밖에 위치하기 때문에, left값이 고정되었던 것이다..!!
그러면 이 선언문들을 함수 안에 집어넣으면 변경된 값이 left에 반영되고, 이벤트가 중첩되는 효과를 볼 수 있지 않을까?

document.addEventListener("keydown", function (e) {
  const heroLeft = heroElement.style.left;

  const heroLeftWithoutPx = Number(heroLeft.split("px")[0]);

  if (e.keyCode === 37) {
    heroElement.style.left = heroLeftWithoutPx - 10 + "px";
    console.log("왼쪽" + (heroLeftWithoutPx - 10) + "px");
    console.log(heroLeft);
  } else if (e.keyCode === 39) {
    heroElement.style.left = heroLeftWithoutPx + 10 + "px";
    console.log("오른쪽" + (heroLeftWithoutPx + 10) + "px");
    console.log(heroLeft);
  }
});


이벤트가 중첩되어 left값이 변하는 것을 볼 수 있다.

캐릭터도 잘 움직인다!

이번에 알게된 것을 통해 이벤트를 1회성으로 하고 싶을 때, 중첩시키고 싶을 때 어떻게 구현해야 하는지 알 것 같았다. 1회성으로 발생시키는 이벤트를 쓰는 경우도 있을 것 같으니 잘 기억해두자.

댓글남기기