마우스 이벤트도 키보드와 마찬가지로 특수키를 제외하고 키가 클릭되었을때 이벤트가 발생하도록 해야한다.
키가 클릭되었을때 active 클래스를 추가해 요소의 색상이 변해야 하고, input에도 값이 들어가야한다.
키보드와 마찬가지로 모든 각각의 key 요소에 이벤트 핸들러를 할당하는 것이 아니라 요소를 모두 감싸고 있는 키보드 엘리먼트에서 이벤트 핸들러를 작성한다. 즉, 이벤트 위임을 사용하는 것이다.
마우스 클릭시 효과 주기
#addEvent() {
// ...
this.#keyboardEl.addEventListener(
"mousedown",
this.#onMouseDown.bind(this)
);
document.addEventListener("mouseup", this.#onMouseUp.bind(this));
}
#onMouseDown(event) {
event.target.closest("div.key")?.classList.add("active");
}
#onMouseUp(event) {
this.#keyboardEl.querySelector(".active")?.classList.remove("active");
}
먼저 이벤트 핸들러를 할당해준다.
마우스가 눌릴 때(mousedown) 동작할 이벤트 핸들러 onMouseDown은 키들을 감싸고 있는 키보드 요소에 할당했다.
이벤트가 동작하게 되면, 우선 이벤트가 발생한 요소가 key인지 확인해야한다.
이벤트가 발생한 요소에 key가 있는지, 있다면 active 클래스를 추가하도록 옵셔널 체이닝을 사용해 작성했다.
.closest() 메서드는 자신을 포함해 조상중 조건을 포함하는 요소가 있는지를 찾는 메서드이다. 숫자키들과 같은 특정한 경우를 위해 사용되었다.
옵셔널 체이닝을 사용했기때문에 만약 이 요소가 key가 아니라면 undefined를 반환하되 에러는 발생하지 않는다.
마우스가 떼어질 때(mouseup) 동작할 이벤트 핸들러는 onMouseUp이다.
onMouseUp은 특정 엘리먼트가 아닌 document에 할당되었는데, 사용자가 마우스를 키보드 밖에서 떼거나, 또는 다른 요소 위에서 떼었을때도 동작하게 하기 위해서이다.
document의 keyboard 요소에서 querySelector로 active 클래스가 있는 요소를 찾아 해당 클래스를 삭제한다.
이렇게 하면 마우스를 눌렀다 떼었을때의 동작이 완성된다.
마우스 클릭시 값 입력하기
#onMouseUp(event) {
const keyEl = event.target.closest("div.key");
const isActive = !!keyEl?.classList.contains("active");
// 없다면 undefined 출력. !! boolean 값으로 확실하게 타입 캐스팅을 시킨다는 내용
const val = keyEl?.dataset.val; // data 속성의 값 가져옴.
if (isActive && !!val && val !== "Space" && val !== "Backspace") {
this.#inputEl.value += val;
}
if (isActive && val === "Space") {
this.#inputEl.value += " ";
}
if (isActive && val === "Backspace") {
this.#inputEl.value = this.#inputEl.value.slice(0, -1);
}
this.#keyboardEl.querySelector(".active")?.classList.remove("active");
}
마우스를 눌렀다 뗄때 값이 입력되도록 작성했다.
값이 입력될때는 세가지 조건을 판단해야한다.
- 이 값은 키보드의 키 요소인가? (key 클래스를 갖고 있는지)
- 이 값은 현재 눌러진 요소인가? (active 클래스를 갖고있는지)
- 이 값은 어떤 data-val을 갖고있는가?
첫번째 변수인 keyEl에서 첫번째 조건을 판단한다. 이벤트가 발생한 요소에서 자신을 포함해 가장 가까운 div.key 요소를 변수에 담는다.
두번째 isActive는 keyEl이 active 클래스를 갖고있는지 판단한다. !가 2개 붙어있는 이유는 값을 더 확실하게 표현하기 위함이다.
세번째 변수인 val은 keyEl의 커스텀 속성인 data-val 값을 가져온다.
키에는 3가지 종류가 있다.
값이 입력되는 일반적인 영문/숫자키인 경우, 스페이스키인 경우, 백스페이스키인 경우이다.
영문/숫자키는 data-val의 값이 입력되게 하고, 스페이스는 공백, 백스페이스의 경우에는 맨 뒤의 요소를 잘라낸 다음 input의 value에 할당한다.
마우스 입력시 키보드 입력 막기
마우스를 입력하면 키보드로 값을 입력할 수 없어야 하고, 키보드로 입력하면 마우스로 클릭해서 값을 입력할 수 없어야한다.
이를 막기 위해서 #keyPress, #mouseDown 변수를 생성했다.
#keyPress = false; // 키보드가 눌리고 있는지
#mouseDown = false; // 마우스가 눌리고 있는지
#onMouseDown(event) {
if (this.#keyPress) return;
this.#mouseDown = true;
// ...
}
#onMouseUp(event) {
if (this.#keyPress) return;
this.#mouseDown = false;
// ...
}
#onKeyDown(event) {
if (this.#mouseDown) return;
this.#keyPress = true;
// ...
}
#onKeyUp(event) {
if (this.#mouseDown) return;
this.#keyPress = false;
// ...
}
키보드가 눌러지고 있는 경우에는 #keyPress가 true가 되고 마우스가 눌러지고 있는 경우에는 #mouseDown이 true가 된다.
각각의 이벤트 제일 상단에 이를 판단하는 조건문을 추가해서 만약 다른 이벤트가 실행중이라면 다음 코드가 실행되지 않고 return으로 빠져나가게 했다.
*******
가상 키보드 만들기가 끝났다! 바닐라 자바스크립트로 만든 내용인데, 클래스 문법을 사용할줄은 몰랐었다.
사실 아직 클래스 문법에는 익숙하지 않아서 코드를 분석하는데 시간이 조금 걸렸다.
이후에는 강의를 보지 않고 혼자서 만들어볼 생각이다. 가능하다면 리액트로 리팩토링도 해보고싶다!
************************
#패스트캠퍼스 #패캠챌린지 #수강료0원챌린지 #환급챌린지 #직장인인강 #직장인자기계발
#패캠인강후기 #패스트캠퍼스후기 #오공완 #30개프로젝트로배우는프론트엔드withReact
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
'study > fastcampus' 카테고리의 다른 글
[React] 이미지 슬라이드 - 2. HTML & CSS (0) | 2023.02.26 |
---|---|
[React] 이미지 슬라이드 - 1. 프로젝트 개요 및 개발환경 설정 (0) | 2023.02.25 |
[React] 가상 키보드 만들기 - 4. 키보드 이벤트 작성 (0) | 2023.02.23 |
[React] 가상 키보드 만들기 - 3. Dark theme, font 변경 (0) | 2023.02.22 |
[React] 가상 키보드 만들기 - 2. html, css 작업 (0) | 2023.02.21 |