Input 이벤트에서 한글 처리하기. event.isComposing이란? (한글 두 번 입력 방지 😸)

프론트엔드 개발을 하다 보면 input 이벤트나 keydown, keyup 이벤트를 다룰 때, 예상치 못한 버그를 마주할 때가 있다.
 
특히 IME(Input Method Editor)를 사용하는 환경(예: 한글 입력)에서 이벤트 핸들러가 엉뚱한 동작을 하거나, 입력값이 두 번 처리되는 등의 문제가 발생할 수 있다.
 
이때 유용하게 활용할 수 있는 속성이 바로 event.isComposing이다.


event.isComposing 🎉

event.isComposing은 사용자가 IME를 사용하여 입력을 조합(Composing)하는 중인지 여부를 나타내는 불리언 값이다.
(한글의 경우에는 자음과 모음, 혹은 또 하나의 자음이 합쳐져 하나의 글자가 되므로, 조합형 글자이다)

  • true
        사용자가 아직 글자를 완성하지 않고 입력을 조합 중인 상태
  • false
        입력이 확정된 상태

즉, 한글 입력처럼 조합형 문자를 사용할 때, 글자가 완성되기 전까지는 event.isComposingtrue로 유지되다가, 최종 입력이 확정될 때 false가 된다 🌟


event.isComposing이 왜 중요한가? (with 예제)

IME 입력을 고려하지 않고 이벤트 핸들러를 작성하면, 한글과 같은 조합형 문자 입력 시 비정상적인 동작이 발생할 수 있다.
 
예를 들어, 다음과 같은 input 이벤트 핸들러를 생각해보자.

const input = document.querySelector("input");
input.addEventListener("input", (event) => {
  console.log("Input event: ", event.target.value);
});

 
이제 사용자가 한글을 입력한다고 가정하자.
 
안녕을 입력하는 과정에서 input 이벤트가 어떻게 발생하는지 확인해 보자.

한글 입력 과정에서의 input 이벤트 흐름

입력 단계 event.target.value를 확인해보면,

입력"ㅇ"
입력"아"
입력"안"
입력"안녕"

 
녕을 '녕' 처럼 한번에 입력하는 경우도 있지만(복붙이나 자동완성 등), 'ㅇ', 'ㅏ', 'ㄴ' 입력이 순서대로 입력되는 경우는 composing 과정이라고 할 수 있다.
 
IME 환경에서는 글자가 완성되기 전에 여러 번의 input 이벤트가 발생할 수 있다. (ㅇ ㅏ ㄴ)
따라서 조합 중인 입력을 무조건 처리하면 의도치 않은 동작을 유발할 수 있다.


event.isComposing을 활용한 해결 방법

이 문제를 해결하려면 event.isComposing을 활용하여 조합 중인 입력을 무시하면 된다.

const input = document.querySelector("input");
input.addEventListener("input", (event) => {
  if (event.isComposing) return; // 조합 중인 입력은 무시
  console.log("Final input: ", event.target.value);
});

이제는 글자가 완성된 후에만 이벤트가 처리되므로, 의도하지 않은 중간 입력값을 방지할 수 있다.


keydown, keyup 이벤트와 isComposing

input 이벤트뿐만 아니라 keydown과 keyup 이벤트에서도 event.isComposing을 활용할 수 있다.
예를 들어, IME 입력 도중에는 Enter 키 이벤트를 무시하고 싶다면 다음과 같이 구현할 수 있다.

input.addEventListener("keydown", (event) => {
  if (event.isComposing && event.key === "Enter") {
    event.preventDefault();
    return;
  }
  console.log("Key pressed: ", event.key);
});

이렇게 하면 한글 입력 도중 Enter 키가 눌려도 이벤트가 실행되지 않도록 막을 수 있다.


😎 요약하자면...

 
IME 입력 환경을 고려하지 않으면 프론트엔드에서 입력 처리 시 예상치 못한 버그가 발생할 수 있다.
특히 한글과 같은 조합형 문자를 입력할 때 event.isComposing을 활용하면 불필요한 이벤트 처리를 방지하고, 보다 안정적인 입력 처리가 가능하다.
 
다음과 같은 상황에서 event.isComposing을 유용하게 활용할 수 있다.

  • input 이벤트에서 조합 중인 입력을 무시
  • keydown, keyup 이벤트에서 조합 중 키 입력을 무시
  • Enter 키와 같은 특수 키 동작을 조합 입력과 분리

IME 환경을 고려하는 것은 국제화를 지원하는 웹 애플리케이션에서 필수적인 요소이다.
event.isComposing을 잘 활용하면 사용자 경험에 문제가 생기는 경우를 방지하고, 더 나은 경험을 제공할 수도 있다.
 
+ React 이벤트에서는 event.navtiveEvent.isComposing 에서 해당 기능을 확인할 수 있다 👻
 
 

참고자료 🍰

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/isComposing

KeyboardEvent: isComposing property - Web APIs | MDN

The KeyboardEvent.isComposing read-only property returns a boolean value indicating if the event is fired within a composition session, i.e. after compositionstart and before compositionend.

developer.mozilla.org

https://stackoverflow.com/questions/77898842/typescript-iscomposing-does-not-exist-on-type-event

Typescript: isComposing does not exist on type Event

In a React app with Typescript i get a Typescript error during compile time and in the editor: TS2339: Property isComposing does not exist on type Event This happens on an OnChange event in a HTML...

stackoverflow.com