Модель управления фокусом в Cleave.js строится вокруг идеи
виртуального разбиения одного DOM-инпута на логические блоки ввода.
Несмотря на то, что на уровне HTML используется один
<input>, библиотека ведёт себя так, как будто поле
состоит из нескольких сегментов. Это напрямую влияет на поведение
курсора, обработку клавиш, переходы между частями значения и реакцию на
удаление символов.
Ключевой особенностью является то, что Cleave.js не создаёт
дополнительных элементов для каждого сегмента. Вместо этого фокус
остаётся в одном input, а навигация реализуется через управление позиции
курсора (selectionStart, selectionEnd) и
трансформацию значения.
Каждое событие ввода проходит через несколько этапов:
keydown, input,
focus, blur)rawValue)После каждого изменения Cleave.js пытается восстановить логическую позицию курсора, соответствующую “сырому” значению, а не форматированному.
Это особенно важно при форматировании чисел, дат и телефонных номеров, где добавляются разделители, влияющие на физические позиции символов.
Основная проблема форматированных input — несоответствие между индексами raw-строки и отображаемой строки.
Cleave.js решает это через построение отображаемого offset-map:
При каждом вводе символа:
Это позволяет сохранять ощущение линейного ввода, даже если строка содержит пробелы, дефисы или скобки.
При вставке символа в середину строки Cleave.js:
Особое внимание уделяется случаям, когда формат добавляет символы
автоматически (например, +7 (___) ___-__-__).
Удаление символов требует обратного отображения:
При этом разделители формата игнорируются как “невидимые” элементы. Это создаёт эффект удаления только значимых символов.
В конфигурациях Cleave.js, где используется несколько логических блоков (например, дата или кредитная карта), навигация реализуется через:
Если курсор достигает конца блока, система может автоматически перемещать его в следующий сегмент, но только при условии полного заполнения текущего.
Важное поведение:
Cleave.js не управляет фокусом DOM напрямую, но предоставляет поведение, которое взаимодействует с внешними системами управления формами.
Типовые сценарии:
element.focus()При программной установке значения:
При этом библиотека пытается минимизировать “прыжки” курсора, характерные для controlled inputs.
При blur Cleave.js фиксирует:
При focus:
Особенность заключается в том, что повторный focus может привести к перерасчёту форматирования, если конфигурация допускает динамические маски.
При использовании нескольких экземпляров Cleave.js в одной форме возникает необходимость координации фокуса между полями.
Типовые схемы поведения:
При этом каждый экземпляр работает независимо, но общая логика формы может реализовывать цепочки фокуса на уровне приложения.
Числовые поля демонстрируют особое поведение:
При вводе длинных чисел алгоритм стремится сохранять относительную позицию внутри числа, а не абсолютный индекс строки.
Autofill создаёт дополнительные сложности для навигации:
input могут агрегироватьсяCleave.js реагирует на это полной переработкой value и принудительной
нормализацией состояния после события change.
Обработка клавиш включает:
Особое внимание уделяется стрелкам: движение игнорирует форматные символы и работает только по логической структуре данных.
На мобильных устройствах Cleave.js учитывает:
При вводе на мобильных клавиатурах курсор часто пересчитывается полностью после каждого символа, чтобы избежать рассинхронизации между raw и formatted состоянием.
Одной из ключевых задач является предотвращение “прыгающего курсора”. Для этого используется стратегия:
Если точное восстановление невозможно, курсор смещается к ближайшей валидной позиции внутри текущего сегмента.
При использовании с React, Vue или Angular управление фокусом часто становится конкурирующим процессом между:
Чтобы избежать конфликтов, Cleave.js опирается на минимальные DOM-операции и не вмешивается в lifecycle фреймворков, ограничиваясь только перерасчётом значения и курсора.
Система имеет ряд ограничений:
Эти ограничения связаны с тем, что вся логика навигации построена поверх одного DOM-элемента без виртуального разделения на реальные input-поля.
Финальный аспект — синхронизация форматирования с активным фокусом.
При активном вводе:
При неактивном фокусе:
Такая двухрежимная модель позволяет балансировать между отзывчивостью и стабильностью интерфейса ввода.