Жизненный цикл экземпляра Cleave

Жизненный цикл экземпляра Cleave.js определяется последовательностью состояний объекта маскировщика, начиная с инициализации и заканчивая полным разрушением связей с DOM. В основе модели лежит идея перехвата ввода пользователя и синхронизации «сырого» значения с форматированным представлением без изменения исходного источника данных.

Жизненный цикл начинается с вызова конструктора new Cleave(...). На этом этапе формируется объект, который связывает DOM-элемент и набор правил форматирования.

При создании выполняются следующие внутренние операции:

  • сохранение ссылки на целевой input-элемент;
  • разбор конфигурационного объекта options;
  • определение типа форматирования (числа, телефон, дата, кастомные блоки);
  • подготовка внутренних буферов для хранения raw и formatted значений;
  • регистрация обработчиков событий ввода.

Ключевой момент: на этапе инициализации библиотека не просто «подписывается» на input, а сразу приводит текущее значение поля к заданному формату. Это означает, что уже существующее значение в DOM может быть перезаписано в соответствии с правилами маски.

Привязка к DOM и установка слушателей событий

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

  • input — основной канал обработки пользовательского ввода;
  • keydown — контроль допустимых символов и поведения клавиш;
  • focus и blur — управление состоянием поля;
  • copy / paste — обработка вставляемых данных.

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

Важно, что библиотека не заменяет нативный input, а расширяет его поведение. DOM остаётся источником истины для UI, но логика значения разделяется на две сущности:

  • rawValue — «чистое» значение без форматирования;
  • value — отображаемое форматированное значение.

Обработка ввода и реактивное форматирование

Каждое изменение значения проходит через внутренний пайплайн обработки:

  1. Извлечение текущего значения из input.
  2. Очистка строки от недопустимых символов.
  3. Применение маски или шаблона форматирования.
  4. Пересборка строки в соответствии с правилами блока.
  5. Обновление DOM-значения.

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

Особенность заключается в том, что форматирование выполняется синхронно с вводом, что создаёт эффект «живой маски».

Состояние экземпляра и внутренние данные

Экземпляр хранит несколько ключевых состояний:

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

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

Дополнительно используется механизм сравнения состояний для предотвращения лишних перерисовок. Если новое значение совпадает с предыдущим, обновление DOM пропускается.

Обновление значения извне

Жизненный цикл экземпляра не ограничивается пользовательским вводом. Внешний код может изменять значение программно.

При установке нового значения через API происходит повторный запуск того же пайплайна обработки, что и при вводе:

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

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

Обработка вставки и автозаполнения

События вставки данных (paste, autofill браузера) обрабатываются отдельно, поскольку они нарушают стандартный поток посимвольного ввода.

На этом этапе:

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

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

Изменение конфигурации и частичная реинициализация

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

При изменении конфигурации:

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

Фактически это промежуточное состояние между «живым» экземпляром и его пересозданием.

Методы управления состоянием

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

  • destroy() — полное отключение экземпляра;
  • setRawValue() — установка «сырого» значения;
  • getRawValue() — получение неформатированного значения;
  • setValue() (в зависимости от версии) — установка отображаемого значения.

Каждый из этих методов влияет на состояние объекта по-разному. Например, setRawValue() запускает форматирование без имитации пользовательского ввода, тогда как setValue() может эмулировать полную цепочку обновления.

Уничтожение экземпляра и освобождение ресурсов

Финальная стадия жизненного цикла наступает при вызове destroy().

В этот момент выполняются следующие операции:

  • удаление всех event listeners с DOM-элемента;
  • очистка внутренних ссылок на состояние;
  • отключение обработчиков форматирования;
  • восстановление исходного поведения input.

После уничтожения объект перестаёт реагировать на изменения DOM. Важно, что сам input остаётся в документе, но теряет всю дополнительную логику форматирования.

Это критично в SPA-приложениях, где компоненты часто монтируются и размонтируются повторно.

Повторная инициализация и повторное использование

После уничтожения экземпляра возможно создание нового объекта на том же DOM-элементе. В этом случае жизненный цикл начинается заново:

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

При этом старое состояние полностью изолируется и не влияет на новый экземпляр.

Особенности синхронизации состояния

Одной из ключевых характеристик жизненного цикла является постоянная синхронизация между тремя слоями:

  • DOM-значение;
  • внутренний raw state;
  • отображаемое formatted state.

Любое рассогласование между этими слоями немедленно исправляется при следующем событии ввода или программного обновления. Это создаёт модель «самовосстанавливающегося» состояния, где DOM никогда не остаётся в неконсистентном виде надолго.

Побочные эффекты и контроль стабильности

В процессе жизненного цикла могут возникать повторные триггеры обновления, особенно при:

  • сложных масках с разделителями;
  • автоматическом форматировании дат;
  • изменении курсора в середине строки;
  • вставке больших фрагментов текста.

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

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