Управление фокусом

Управление фокусом в Inputmask строится вокруг синхронизации поведения маски с DOM-событиями focus, blur, кликами по полю ввода и программной установкой курсора. Маска не только форматирует ввод, но и активно вмешивается в позиционирование каретки, отображение плейсхолдера и реакцию на смену активного элемента формы.

При инициализации Inputmask навешивает обработчики событий фокуса на целевой элемент. Основные точки входа:

  • focus — активация поля
  • blur — потеря фокуса

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

  • showMaskOnFocus — определяет, отображать ли полную маску при входе в поле
  • clearMaskOnLostFocus — управляет очисткой незаполненной маски при уходе из поля
Inputmask({
  mask: "+7 (999) 999-99-99",
  showMaskOnFocus: true,
  clearMaskOnLostFocus: false
}).mask(document.querySelector("#phone"));

При showMaskOnFocus: true поле при активации заполняется шаблоном, даже если данных нет. Это важно для визуальной структуры ввода, особенно в телефонных и датированных масках.

При потере фокуса (blur) Inputmask анализирует содержимое поля. Если введённые данные не соответствуют маске и включён clearMaskOnLostFocus, значение сбрасывается.

Inputmask({
  mask: "99/99/9999",
  clearMaskOnLostFocus: true
}).mask(input);

Управление позицией каретки

Одной из ключевых задач Inputmask является контроль позиции курсора. Без этого маска становится неудобной при частичном вводе или редактировании.

positionCaretOnClick

Опция определяет, куда устанавливается каретка при клике:

  • lvp (last valid position)
  • radixFocus (для числовых масок с разделителем)
  • select (выделение всего поля)
  • none (отключение автоустановки)
Inputmask({
  alias: "numeric",
  positionCaretOnClick: "radixFocus"
}).mask(input);

При значении radixFocus курсор автоматически перемещается к десятичному разделителю, что важно для финансовых полей.

positionCaretOnTab

Определяет поведение при переходе через Tab:

  • select — выделение содержимого
  • radixFocus — фокус на дробной части
  • none — стандартное поведение браузера
Inputmask({
  alias: "decimal",
  positionCaretOnTab: "select"
}).mask(input);

Программное управление фокусом

Inputmask не заменяет стандартные методы DOM, но расширяет их поведение через маску.

focus() и blur()

Работа с фокусом остаётся на уровне DOM-элемента:

const el = document.querySelector("#phone");
const im = Inputmask("+7 (999) 999-99-99").mask(el);

el.focus();

При вызове focus() Inputmask перехватывает событие и корректирует каретку в соответствии с настройками.

В некоторых версиях используется внутренний метод:

el.inputmask.focus();
el.inputmask.blur();

Это позволяет синхронизировать поведение маски с внутренним состоянием плагина.

Поведение каретки при инициализации

После применения маски Inputmask определяет начальную позицию ввода. Она зависит от:

  • наличия значения в поле
  • наличия плейсхолдера
  • режима showMaskOnFocus
  • типа маски (статическая или динамическая)

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

Inputmask({
  mask: "9999-9999",
  placeholder: "_",
  showMaskOnFocus: true
}).mask(input);

Если включён placeholder, Inputmask рассчитывает первую “разрешённую” позицию, пропуская фиксированные символы маски.

Поведение при клике и выделении

Клик по полю обрабатывается с перерасчётом позиции каретки. Inputmask анализирует:

  • координату клика
  • ближайший допустимый слот ввода
  • правила маски

Дополнительно влияет:

  • greedy — влияет на заполнение и визуальную длину
  • autoUnmask — изменяет отображаемое значение и может влиять на выделение
Inputmask({
  mask: "999-999",
  greedy: false,
  positionCaretOnClick: "lvp"
}).mask(input);

При greedy: false маска может вести себя более “гибко”, сокращая видимую длину и изменяя логику позиционирования.

Влияние showMaskOnHover и showMaskOnFocus

Хотя showMaskOnHover напрямую относится к наведению, он влияет на фокусное поведение косвенно: при переходе мышью в поле пользователь уже видит структуру ввода.

Inputmask({
  mask: "99/99/9999",
  showMaskOnHover: true,
  showMaskOnFocus: true
}).mask(input);

Комбинация этих опций делает поведение поля стабильным: структура маски видна до активации и сохраняется после получения фокуса.

Сохранение и восстановление позиции курсора

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

  • пересоздание маски
  • повторная установка значения
  • явное управление selection range
const el = document.querySelector("#phone");

el.inputmask.setValue("1234567890");
el.inputmask.setCaret(el, 4, 4);

Метод setCaret задаёт диапазон выделения, что позволяет фиксировать позицию ввода после внешних изменений.

Автозаполнение и фокус

При автозаполнении браузером Inputmask перехватывает событие input и перерассчитывает маску. Однако поведение фокуса может отличаться:

  • поле может не получать явный focus
  • значение вставляется целиком
  • каретка устанавливается в конец или первую валидную позицию

Для стабилизации поведения используется обработка onBeforePaste:

Inputmask({
  mask: "9999 9999 9999 9999",
  onBeforePaste: function (pastedValue) {
    return pastedValue.replace(/\s+/g, "");
  }
}).mask(input);

После вставки Inputmask пересчитывает позицию каретки согласно правилам маски.

Особенности поведения на мобильных устройствах

На мобильных браузерах управление фокусом осложняется системной клавиатурой:

  • каретка может смещаться после открытия клавиатуры
  • событие focus иногда срабатывает с задержкой
  • автокоррекция влияет на позицию ввода

Inputmask компенсирует это через повторное вычисление позиции после focus и input.

Особенно важно сочетание:

  • showMaskOnFocus
  • корректного placeholder
  • минимального вмешательства в native selection API

Работа с tab и переходами между полями

При переходе через Tab Inputmask может:

  • сохранить позицию
  • переместить каретку в начало
  • выделить всё значение
Inputmask({
  mask: "999-99-9999",
  positionCaretOnTab: "select"
}).mask(input);

Это особенно важно в формах с последовательным вводом данных, где пользователь быстро перемещается между полями.

Внутренние события фокуса

Inputmask предоставляет набор хуков, связанных с фокусом:

  • onBeforeFocus
  • onFocus
  • onBeforeBlur
  • onBlur
Inputmask({
  mask: "99-99",
  onBeforeFocus: function () {
    return true;
  },
  onBlur: function () {
    console.log("blurred");
  }
}).mask(input);

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

Синхронизация фокуса и маски при динамических изменениях

При изменении маски во время активного фокуса возможны нарушения позиции каретки. Inputmask в таких случаях:

  • пересчитывает маску
  • пытается сохранить текущую позицию
  • при невозможности переносит каретку в ближайший допустимый слот
el.inputmask.option({
  mask: "9999-9999"
});

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