FrontEnd/HTML5 & CSS & JavaScript

[JavaScript] 한글 키보드 입력 시 이벤트가 두 번 호출되는 경우

푸고배 2022. 5. 2. 17:39

문제상황

 

 

Ant Design의 Input에 onPressEnter를 사용하는 중 위와 같은 문제가 발생했다.

텍스트를 입력하고 엔터를 누르면 Select의 옵션 값으로 추가가 되도록 구현했는데, 함수가 두 번씩 호출되어 텍스트의 마지막 글자가 옵션값에 추가가 되어버렸다.

 

해결 방법

onKeyDown/onKeyUP 그리고 onKeyPress

onKeyDown, onKeyUp

  • 키를 누르고 떼는 동작 자체에 반응
  • 문자, 숫자, Ctrl, Shift, Alt, F1~F12, Scroll Lock, Pause, Enter를 인식하고 한/영, Print Screen은 인식하지 못함

onKeyPress

  • 위와 달리 문자가 실제로 입력됐을 때 반응
  • 따라서 문자, 숫자, Ctrl, Shift, Alt, F1~F12, Scroll Lock, Pause, Enter, 한/영, Print Screen과 같은 키들을 인식하지 못함

만약 onKeyPress를 사용해도 상관없는 로직이라면 단순히 onKeyDown/onKeyUp 함수를 onKeyPress 함수로 변경하면 문제를 해결할 수 있다.

하지만, Ant Design의 onPressEnter는 엔터값을 입력받는지 체크하는 함수임으로, 합성이벤트(SyntheticEvent)로 onKeyDown을 사용하고 있다.

 

KeyboardEvent.isComposing

onKeyDown을 사용하면서, 한글 입력문제를 해결하는 방법은 없을까?

한글을 입력할 때 자세히 보면 입력 중인 글자 바로 아래에 검은 밑줄이 생기는데, 이 밑줄이 보이는 상황에서 Enter 키를 입력하면 이벤트가 두번 호출되는 문제가 발생하게 된다. 왜냐하면 글자의 조합 중인지, 끝난 상태인지 파악하기 어렵기 때문이다.

 

한글은 자음과 모음의 조합으로 한 음절이 만들어지기 때문에 조합문자이며, 영어는 한 음절이 하나의 알파벳으로 이루어지므로 조합문자가 아니다.

 

해당 이슈가 영어를 입력할 때는 발생하지 않고, 한글을 입력할 때만 발생하는 이유이다.

 

KeyboardEvent.isComposing은 입력된 문자가 조합 문자인지 아닌지를 반환하는 함수로, 이벤트 내부에e.nativeEvent.isComposing을 호출해보면 첫 번째로 호출되는 이벤트는 ture를 반환하고 두 번째 이벤트에서는 false를 반환하는 것을 확인 할 수 있다.

 

즉, 글자가 조합되는 과정에 발생하는 이벤트는 무시되고, 이벤트가 끝난 뒤 발생하는 이벤트에 대해서만 처리를 하도록 구현할 수 있다.

 


Reference

 

[JS] keydown/keyup에서 한글 입력 시 함수가 두 번 실행되는 경우

MailedIt! 서비스를 개발하다 오랫동안 해결하지 못한 에러가 있었다.

velog.io

 

Add onPressEnter for select component · Issue #5942 · ant-design/ant-design

What problem does this feature solve? When we use Select with 'combobox' mode, we usually do some thing when user press Enter, like do a search action. Hope to support this feature. What do...

github.com

 

[React] onKeyDown, onKeyUp, onKeyPress 차이

기존의 자바스크립트에서는 onkeydown, onkeypress, onkeyup 명으로 이벤트를 사용했었습니다. 하지만, react에서는 onKeyDown, onKeyPress, onKeyUp 이벤트는 camelCase 형식의 명칙을 사용합니다. onKeyDown, on..

itprogramming119.tistory.com

 

반응형