Skip to content

브라우저·플랫폼별 IME 동작 차이

검증된 테스트 결과 기반의 브라우저/플랫폼/IME 조합별 정확한 동작

이 문서는 검증된 사실만 기록한다. “~할 수 있다”가 아니라 “~한다” 또는 “~하지 않는다”로 기술한다.


1.1 딕테이션(음성 입력): composition 이벤트 미발생

Section titled “1.1 딕테이션(음성 입력): composition 이벤트 미발생”
항목
버그 IDWebKit Bug 261764
상태OPEN (2026-02 기준 미해결)
보고일2023-09-19
영향 버전iOS 15.7.2, 16.6.1, 17.0 이상 (현재까지 모든 버전)
Apple Radarrdar://problem/115811978

동작:

  • 딕테이션 버튼(마이크)으로 음성 입력 시 compositionstart, compositionupdate, compositionend 이벤트가 발생하지 않는다.
  • beforeinputinput 이벤트만 발생한다.
  • inputTypeinsertText다.

macOS Safari와의 차이:

  • macOS Safari에서는 딕테이션 시 composition 이벤트가 정상 발생한다.
  • 이 문제는 iOS/iPadOS 전용 버그다.

처리 방법:

// iOS Safari 딕테이션은 composition 없이 input만 온다
el.addEventListener('input', (e) => {
if (e.inputType === 'insertText' && !isComposing) {
// 커서 위치에 e.data 삽입
insertText(e.data);
}
});

1.2 한글 입력: composition 이벤트 발생 여부가 불규칙

Section titled “1.2 한글 입력: composition 이벤트 발생 여부가 불규칙”
항목
증상한글 입력 시 compositionstart가 발생하지 않고 insertText만 오는 경우가 있음
재현 조건iOS Safari + 기본 한글 키보드, 일부 서드파티 키보드
원인WebKit이 iOS 키보드 이벤트를 composition으로 처리하지 않는 경우가 있음

동작 패턴 (테스트 결과):

[패턴 A: composition 발생]
사용자: ㄱ → ㅏ → 스페이스
이벤트: compositionstart → compositionupdate("ㄱ") → compositionupdate("가") → compositionend("가")
[패턴 B: composition 미발생]
사용자: ㄱ → ㅏ → 스페이스
이벤트: input(insertText, "가")

패턴 B가 발생하는 경우:

  • 빠르게 입력할 때
  • 일부 서드파티 키보드 사용 시
  • iOS 버전/키보드 설정에 따라 다름

처리 방법:

let isComposing = false;
el.addEventListener('compositionstart', () => { isComposing = true; });
el.addEventListener('compositionend', (e) => {
isComposing = false;
commit(e.data);
});
el.addEventListener('input', (e) => {
// composition 없이 insertText가 오면 바로 commit
if (!isComposing && e.inputType === 'insertText') {
commit(e.data);
}
});
inputTypeiOS Safari 발생 여부
insertText발생
insertCompositionText발생하지 않음
deleteContentBackward발생
deleteWordBackward발생 (단어 삭제 제스처 시)
insertReplacementText발생 (자동 수정 시)

핵심 사실:

  • iOS Safari는 insertCompositionText inputType을 사용하지 않는다.
  • Input Events Level 2 명세에는 조합 중 삽입 시 insertCompositionText를 사용하도록 정의되어 있으나, WebKit/iOS Safari는 이를 구현하지 않았다.
  • beforeinputinputType으로 “조합 중”을 판단하면 안 된다.

2.1 keydown/keyup과 composition 이벤트 순서

Section titled “2.1 keydown/keyup과 composition 이벤트 순서”
항목
버그 IDWebKit Bug 165004
상태OPEN (2026-02 기준)
보고일2016
원인WebKit이 IE 동작에 맞추려고 의도적으로 구현한 것 (현재는 불필요)

Safari 실제 순서:

1. compositionstart
2. compositionupdate
3. input
4. keydown
5. keyup

W3C 명세 순서:

1. keydown
2. compositionstart
3. compositionupdate
4. input
5. keyup

영향:

  • keydown 시점에 isComposing이 이미 true여야 하는데, Safari에서는 composition이 먼저 끝나고 keydown이 온다.
  • Enter로 조합을 확정할 때 keydown.isComposingfalse로 올 수 있다.

처리 방법:

el.addEventListener('keydown', (e) => {
// Safari 보완: keyCode 229면 IME가 처리 중
if (e.isComposing || e.keyCode === 229) {
return; // 단축키 처리하지 않음
}
// 단축키 처리
});
항목
버그 IDWebKit Bug 164369
증상일본어/데드키 조합 중 요소가 blur되면 compositionend가 발생하지 않음
Chrome/Firefoxblur 시 compositionend 발생

처리 방법:

let isComposing = false;
let preeditText = '';
el.addEventListener('compositionstart', () => { isComposing = true; });
el.addEventListener('compositionupdate', (e) => { preeditText = e.data; });
el.addEventListener('compositionend', (e) => {
isComposing = false;
preeditText = '';
commit(e.data);
});
el.addEventListener('blur', () => {
if (isComposing) {
// Safari: compositionend가 안 오므로 강제로 정리
isComposing = false;
// 정책에 따라: preeditText를 commit하거나 버림
preeditText = '';
}
});

3.1 Enter 시 compositionend 조기 발생

Section titled “3.1 Enter 시 compositionend 조기 발생”
항목
버그 IDMozilla Bug 1675313
영향 버전Firefox 84+ (Windows)
증상CJK IME 조합 중 Enter 누르면 compositionend가 keyup에서 조기 발생

문제 시나리오:

사용자: 일본어 "あ" 입력 중 Enter
기대: compositionend("あ") → 줄바꿈 또는 폼 제출
실제: compositionend(미확정 문자열) → 폼에 "あ" 대신 "a"가 제출됨

처리 방법:

el.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && e.isComposing) {
// Enter를 IME에 넘기고 직접 처리하지 않음
return;
}
if (e.key === 'Enter') {
submitForm();
}
});

항목
동작소프트 키보드로 입력 시 거의 모든 keydownkeyCode가 229
원인Android IME가 모든 키를 가로채서 처리하므로 브라우저에 실제 키 코드가 전달되지 않음

실제 로그:

// Android Chrome에서 "가" 입력 시
keydown: key="Process", keyCode=229
compositionstart: data=""
compositionupdate: data="ㄱ"
compositionupdate: data="가"
keydown: key="Process", keyCode=229 // 다음 글자 입력
compositionend: data="가"

처리 방법:

  • keydownkeyCode에 의존하지 않는다.
  • 텍스트 내용은 compositionupdate.data, compositionend.data, input.data에서만 얻는다.

IME”가” 입력 시 compositionupdate 횟수
Microsoft 한글2회: "ㄱ", "가"
Google 한글 입력기2회: "ㄱ", "가"

이벤트 순서:

compositionstart (data: "")
compositionupdate (data: "ㄱ")
compositionupdate (data: "가")
input (inputType: insertCompositionText, data: "가")
compositionend (data: "가")
input (inputType: insertText, data: "가") // 일부 버전

환경composition 이벤트beforeinput inputTypekeyCode주의점
iOS Safari 딕테이션발생 안 함insertText229input만으로 처리
iOS Safari 한글불규칙insertText (insertCompositionText 없음)229composition 없이 올 수 있음
macOS Safari발생insertCompositionText229이벤트 순서 역전, blur 시 compositionend 없음
Firefox (Windows)발생insertCompositionText실제 키Enter 시 조기 compositionend
Android Chrome발생insertCompositionText항상 229keyCode 의존 금지
Chrome/Edge (Windows)발생insertCompositionText229정상 동작

날짜브라우저변경 내용
2016SafariBug 165004 보고 (이벤트 순서) - 2026-02 현재 미해결
2023-09iOS SafariBug 261764 보고 (딕테이션) - 2026-02 현재 미해결
Firefox 84FirefoxBug 1675313 (Enter compositionend)