Позиция курсора при фокусе

В интерфейсах ввода числовых значений библиотека AutoNumeric управляет не только форматированием числа, но и поведением текстового курсора (caret), который определяет позицию ввода внутри поля. При получении фокуса input-элементом именно логика установки позиции курсора становится критической частью UX, так как форматированные значения содержат разделители тысяч, символы валют, фиксированные знаки после запятой и другие визуальные элементы, не являющиеся частью «сырых» данных.

Работа с курсором при фокусе затрагивает несколько уровней: DOM-события, внутреннее представление значения AutoNumeric, а также синхронизацию между отображаемым форматом и фактическим числом.


Модель поведения AutoNumeric при фокусировке

При активации поля ввода библиотека перехватывает событие focus и выполняет ряд преобразований:

  • перевод отображаемого значения в формат, удобный для редактирования;
  • пересчёт позиции курсора с учётом разделителей;
  • применение настроек, связанных с выделением или позиционированием каретки;
  • синхронизация внутреннего состояния с DOM.

Ключевой момент заключается в том, что отображаемая строка может отличаться от редактируемого представления. Например:

1 234 567.89   → визуальный формат
1234567.89      → логическое значение

При переходе в режим редактирования AutoNumeric должен определить, куда именно поставить курсор: в начало, конец, либо оставить его в логически соответствующей позиции.


Параметры управления курсором

selectOnFocus

Опция определяет поведение выделения при получении фокуса. Возможные сценарии:

  • полное выделение значения;
  • отсутствие выделения;
  • частичное выделение в зависимости от состояния поля.

Полное выделение часто используется в формах, где ввод нового значения полностью заменяет старое. В этом случае позиция курсора не играет роли, так как весь текст становится выбранным диапазоном.


caretPositionOnFocus

Настройка, определяющая позицию курсора при активации поля. Основные стратегии:

  • установка курсора в начало строки;
  • установка курсора в конец строки;
  • попытка сохранить логическую позицию относительно числового значения;
  • вычисление позиции с учётом маски форматирования.

При наличии разделителей тысяч простое позиционирование по строковому индексу становится некорректным, поэтому используется трансляция между форматированной и «чистой» строкой.


focus behavior при уже существующем значении

Если поле уже содержит значение, поведение зависит от конфигурации:

  • при строгом режиме форматирования курсор может автоматически смещаться за последний значимый символ;
  • при режиме редактирования сохраняется последняя логическая позиция;
  • при включённом выделении значение полностью подсвечивается.

Особенность заключается в том, что визуальная позиция курсора может не совпадать с индексом строки DOM.


Пересчёт позиции курсора с учётом форматирования

AutoNumeric поддерживает внутренний механизм трансформации индексов. Основная задача — сопоставить:

  • индекс в отформатированной строке;
  • индекс в «сыром» числовом представлении.

Пример:

Отображение: 12 345,67
Индекс DOM:  0 12 345 67
Число:       12345.67

Разделители пробела и запятой не входят в числовую модель, поэтому при установке курсора учитываются только значимые символы.

Алгоритм включает:

  1. анализ форматированной строки;
  2. построение карты соответствия символов;
  3. исключение разделителей;
  4. вычисление корректного смещения.

Сценарии поведения при фокусе

Пустое поле

При отсутствии значения курсор всегда устанавливается в начало или конец поля в зависимости от конфигурации. В этом состоянии нет необходимости учитывать форматирование.


Поле с предварительно заданным значением

При наличии числа AutoNumeric выполняет:

  • форматирование строки;
  • вычисление позиции последнего значимого символа;
  • установку курсора с учётом маски.

Например, для значения с фиксированной дробной частью курсор часто устанавливается перед дробной частью, если она уже присутствует.


Повторный фокус

При повторном получении фокуса после потери активности возможно сохранение последней позиции курсора. Это требует хранения состояния:

  • индекс символа;
  • логическая позиция в числовом значении;
  • флаг модификации поля.

При активации выполняется обратное преобразование в DOM-позицию.


Влияние разделителей и символов форматирования

Разделители тысяч, валютные символы и суффиксы создают дополнительный слой сложности. Они могут:

  • занимать позиции в DOM-строке;
  • не иметь соответствия в числовой модели;
  • изменять длину строки при переключении формата.

Пример:

€ 1 234,56

Здесь символ валюты и пробелы не участвуют в вычислении значения, но влияют на индекс курсора. Поэтому позиционирование требует фильтрации служебных символов.


Обработка событий focus и focusin

AutoNumeric использует DOM-события для синхронизации состояния:

  • focus — первичная активация поля;
  • focusin — всплывающее событие для контейнеров;
  • blur — фиксация значения и нормализация формата.

При событии focus происходит подготовка поля к редактированию, включая корректировку курсора. В некоторых режимах значение временно переводится в нефоматированный вид, чтобы упростить редактирование.


Взаимодействие с IME и вводом сложных символов

При использовании методов ввода (IME, восточные языки) позиция курсора может изменяться асинхронно. В таких случаях:

  • AutoNumeric откладывает пересчёт позиции;
  • фиксируется промежуточное состояние ввода;
  • после завершения композиции (compositionend) выполняется повторная синхронизация.

Это предотвращает «прыжки» курсора внутри поля.


Ограничения при программной установке фокуса

При вызове element.focus() из JavaScript поведение может отличаться от пользовательского взаимодействия:

  • браузер может игнорировать установку курсора до следующего тик-события;
  • AutoNumeric может ещё не завершить инициализацию форматирования;
  • требуется отложенная установка позиции через requestAnimationFrame или аналогичные механизмы.

Типичная схема:

element.focus();

requestAnimationFrame(() => {
  // восстановление позиции курсора
});

Согласование курсора и внутреннего состояния

Внутреннее состояние AutoNumeric включает:

  • текущее числовое значение;
  • форматированную строку;
  • позицию курсора в логическом представлении;
  • флаги редактирования.

При фокусе выполняется синхронизация всех компонентов, чтобы исключить рассогласование между отображением и моделью данных. Несоответствие может приводить к:

  • смещению курсора после первого ввода символа;
  • перескакиванию через разделители;
  • автоматической коррекции позиции.

Типовые паттерны поведения курсора

Редактирование справа налево в числовом поле

Курсор удерживается перед дробной частью, предотвращая случайное изменение целой части числа.

Замена значения целиком

При включённом выделении курсор не позиционируется, так как весь текст уже выбран.

Пошаговый ввод

Курсор перемещается с учётом только значимых символов, игнорируя форматирование.


Стабильность позиции при динамическом форматировании

При вводе цифр AutoNumeric может изменять строку в реальном времени:

  • добавление разделителей;
  • округление дробной части;
  • перенос символов.

Каждое изменение требует пересчёта позиции курсора. Без этого возникает эффект «дрожания», когда каретка смещается после каждого символа.

Механизм стабилизации включает:

  • фиксацию логической позиции;
  • пересчёт DOM-индекса после форматирования;
  • восстановление позиции в обновлённой строке.

Итоговая модель поведения

Позиция курсора при фокусе в AutoNumeric определяется комбинацией факторов:

  • настройка поведения выделения;
  • стратегия установки каретки;
  • форматирование строки;
  • наличие разделителей и валютных символов;
  • состояние предыдущего ввода;
  • синхронизация DOM и внутренней модели.

Корректная реализация требует постоянного преобразования между отображаемой строкой и числовым значением с учётом всех служебных символов форматирования.