케이스 ce-0268-caret-jump-chrome-mobile-ko · 시나리오 scenario-caret-jump-chrome-mobile

Chrome Mobile에서 특정 문자 입력 시 캐럿 점프

OS: Android 10-14 기기: Mobile (Samsung Galaxy, Pixel, etc.) Any 브라우저: Chrome for Android 120+ 키보드: English (QWERTY) 초안
caretcursorchromemobileandroidpunctuation

현상

Chrome Mobile(안드로이드)에서 단어 중간에 특정 문장 부호를 입력하면 캐럿이 입력점이 아니라 단어 끝으로 점프합니다.

재현 예시

  1. Chrome Mobile 브라우저에서 contenteditable 요소에 포커스합니다.
  2. 단어를 입력합니다 (예: “California”).
  3. 커서를 단어 중간으로 이동합니다 (예: “Califor” 뒤, “nia” 앞).
  4. 쉼표(,)를 입력합니다.

관찰된 동작

  • 캐럿 점프: 캐럿이 쉼표 뒤(입력점)이 아니라 “California” 끝으로 점프함
  • 수동 클릭 필요: 캐럿이 이상한 위치로 이동하면, 올바른 위치에 다시 클릭해야 함
  • 편집 불가: 해당 문장 부호를 사용하면 편집이 매우 어려워짐
  • Chrome Mobile 특유: Desktop Chrome, Firefox Mobile, iOS Safari에서는 발생하지 않음

예상 동작

  • 캐럿이 입력점에 유지되어야 함
  • 바로 다음 글자를 입력할 수 있어야 함

참고사항 및 가능한 해결 방향

  • setTimeout 사용: input 이벤트 후 짧은 지연으로 캐럿 위치 복원
  • beforeinput/input 감지: 캐럿 점프를 감지하고 자동으로 복원
  • 캐럿 위치 저장: beforeinput에서 캐럿 위치를 저장했다가 input에서 비교
  • 사용자 안내: 해당 이슈가 발생할 수 있음을 알리거나 데스크탑 사용 권장
  • 대안 브라우저: 모바일에서 편집이 어려울 경우 데스크탑 브라우저 사용 안내

코드 예시

const editor = document.querySelector('div[contenteditable]');
let lastCaretPosition = null;
let isChromeMobile = /Chrome\/[\d.]+/.test(navigator.userAgent) && /Android/.test(navigator.userAgent);

editor.addEventListener('beforeinput', (e) => {
  const selection = window.getSelection();
  if (selection.rangeCount > 0) {
    const range = selection.getRangeAt(0);
    lastCaretPosition = {
      node: range.startContainer,
      offset: range.startOffset
    };
    console.log('Before input, caret at:', lastCaretPosition.offset);
  }
});

editor.addEventListener('input', (e) => {
  if (!isChromeMobile) return;
  
  const selection = window.getSelection();
  if (selection.rangeCount > 0 && lastCaretPosition) {
    const range = selection.getRangeAt(0);
    const currentOffset = range.startOffset;
    const distance = Math.abs(currentOffset - lastCaretPosition.offset);
    
    // 캐럿 점프 감지 (2글자 이상 차이)
    if (distance > 2) {
      console.warn('Cursor jump detected:', lastCaretPosition, {node: range.startContainer, offset: currentOffset});
      
      // 캐럿 복원
      const restoreRange = document.createRange();
      restoreRange.setStart(lastCaretPosition.node, lastCaretPosition.offset);
      restoreRange.collapse(true);
      selection.removeAllRanges();
      selection.addRange(restoreRange);
      
      console.log('Caret restored to:', lastCaretPosition.offset);
    }
  }
});

이 시나리오의 변형

케이스 OS 브라우저 상태
ce-0268-caret-jump-chrome-mobile-ko Android 10-14 Chrome for Android 120+ 초안
ce-0269-caret-jump-chrome-mobile-ios-en-ko iOS 16+ Safari 16+ 확인됨
ce-0270-caret-jump-chrome-mobile-firefox-en-ko Windows 10/11 Firefox 120+ 확인됨

Playground for this case

Use the reported environment as a reference and record what happens in your environment while interacting with the editable area.

Reported environment
OS: Android 10-14
Device: Mobile (Samsung Galaxy, Pixel, etc.) Any
Browser: Chrome for Android 120+
Keyboard: English (QWERTY)
Your environment
Sample HTML:
Event log
Use this log together with the case description when filing or updating an issue.
0 events
Interact with the editable area to see events here.