iOS 모바일 웹의 조합 중인 한글 제거

숨겨진 input을 통해 조합중인 한글 제거하는 방법

Statue of King Sejong"Statue of King Sejong" by KOREA.NET - Official page of the Republic of Korea is licensed under CC BY-SA 2.0

한글 입력기

모바일 iOS 뿐만 아니라 한글 입력기는 보통 조합이 완전히 끝나지 않은 상태를 저장한다. (예를들면 ‘호크니’ 라고 입력했을 때 ‘니’는 아직 조합중이라 어딘가에 상태를 저장해두고 있다) 이렇게 하는 이유는 입력의 결과가 항상 정규화된 유니코드여야 하기 때문이다.1 예를 들면 한글 입력기는 다음과 같은 프로세스로 입력을 처리한다.

  1. 한글 키보드에서 를 입력한다
  2. 출력(입력창 등에 표시되는 값)으로 을, 입력 버퍼에 를 저장한다
  3. 한글 키보드에서 를 입력한다
  4. 현재 입력 컨텍스트에서 마지막 글자를 지우고, 를 출력, 입력 버퍼에 를 저장한다

웹 텍스트 입력창에서 이전 입력 값이 남는 문제

대개는 입력기에서 엔터를 입력하면 조합상태가 끝난 것으로 보고 조합을 끝내기 때문에, 입력기 버퍼에서 조합 중인 글자를 지워 준다. 하지만 엔터가 아닌 웹 버튼 등으로 전송을 하고 텍스트를 지우면 버퍼가 남아있는 문제가 있다. 그래서 다음과 같은 버그가 발생할 수 있다.

  1. 채팅창에서 ‘ㅎ’, ‘ㅗ’ 를 입력한다
  2. 채팅창에 ‘호’가 입력된다
  3. 전송 버튼을 누른다
  4. 채팅창에서 ‘ㅋ’ 를 입력한다
  5. 채팅창에 ‘홐’이 입력된다

하지만 대부분의 모바일 채팅 경험에서는 엔터 입력이 줄바꿈으로 처리되고, 전송이 아니기 때문에 반드시 전송은 버튼을 통해서 이루어져야 했고 따라서 자바스크립트를 통해 직접 버퍼를 지우는 작업이 필요했다.

강제로 입력기의 버퍼 지우기

근본적으로는 버튼을 눌렀을 때 웹브라우저가 한글 입력기의 버퍼를 지워주어야 하겠지만, iOS 모바일 웹에서는 그러한 처리가 되어있지 않아 이를 회피할 방법이 필요했다.

  • 엔터 혹은 스페이스 입력
  • 입력창의 포커스 없애기

손쉬운 해결법 중 한 가지는 새로운 입력창에 포커스가 가는 경우 입력기가 버퍼를 지운다는 점을 이용하는 것이다. 숨겨진 <input>을 하나 만들어 두고 전송버튼을 누를 때마다 사용자 몰래 포커스를 바꾼 다음 원래의 포커스로 돌려준다.

예시 코드

예시에서 CLEAR는 버그 상황을, CLEAR BUFFER는 버그가 해결된 상황을 재연한다. 모바일 iOS에서 확인할 수 있다. https://codepen.io/kidkkr/pen/VwYvryb

See the Pen Clear input buffer with hidden input by kidkkr (@kidkkr) on CodePen.


  1. Pusnow님이 작성한 한글과 유니코드 에 가면 좀 더 친절한 설명을 볼 수 있다. 본문에서는 한글 입력기 내부적으로는 NFD 배열을, 출력으로는 NFC 형태로 내보내는 것을 의도했다.