Интеграция со стандартными событиями

Работа с AutoNumeric неизбежно затрагивает стандартную модель событий DOM, поскольку библиотека не заменяет её, а расширяет поведение input-элементов за счёт форматирования отображаемого значения и управления «сырым» значением. При интеграции со стандартными событиями ключевая задача заключается в том, чтобы сохранить предсказуемость native-событий, не нарушая их порядок и не создавая бесконечных циклов обновления при программном изменении значения.

После инициализации AutoNumeric input продолжает оставаться обычным HTML-элементом <input>, однако его значение разделяется на два уровня:

  • отформатированное значение (formatted) — то, что видит пользователь;
  • сырое значение (rawValue) — числовое представление без форматирования.

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

Интеграция с событием input

Событие input является основным механизмом отслеживания изменений в поле. AutoNumeric перехватывает пользовательский ввод и преобразует его в форматированное значение, при этом оставляя возможность реагировать на изменения в реальном времени.

Типичная схема взаимодействия:

  • пользователь вводит символ;
  • AutoNumeric нормализует ввод;
  • обновляется отображаемое значение;
  • триггерится событие input.

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

Пример обработки:

const input = document.querySelector('#amount');

input.addEventListener('input', (event) => {
  const value = event.target.value; // форматированное значение
});

При необходимости получения числового значения используется API библиотеки:

const numericValue = autoNumericInstance.getNumber();

Событие change и потеря фокуса

Событие change в контексте AutoNumeric срабатывает по стандартным правилам DOM — при потере фокуса, если значение было изменено. Однако важное отличие заключается в том, что сравнение происходит уже на уровне отформатированного значения.

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

Пример:

input.addEventListener('change', (event) => {
  console.log(event.target.value);
});

focus и blur в контексте форматирования

События focus и blur часто используются для переключения между отображением форматированного и «чистого» значения.

AutoNumeric может работать в режиме, где при фокусе значение становится более «редактируемым», а при потере фокуса возвращается форматирование (например, добавляются разделители тысяч).

Типовая логика:

input.addEventListener('focus', () => {
  // возможное упрощение отображения при фокусе
});

input.addEventListener('blur', () => {
  // восстановление форматированного вида
});

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

Проблема циклических обновлений

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

Типичный сценарий:

  1. обработчик input вызывает set() или изменение значения;
  2. AutoNumeric обновляет DOM;
  3. снова срабатывает input;
  4. возникает цикл.

Для предотвращения этого используется проверка источника изменения или временное отключение обработчиков.

Пример защиты:

let isProgrammatic = false;

input.addEventListener('input', (e) => {
  if (isProgrammatic) return;

  const value = e.target.value;
});

function updateValue(newValue) {
  isProgrammatic = true;
  autoNumericInstance.set(newValue);
  isProgrammatic = false;
}

Синхронизация с form-событиями

AutoNumeric корректно интегрируется с формами HTML, но важно учитывать, что при отправке формы используется текущее значение input, которое может быть форматированным.

Для получения числового значения перед отправкой формы обычно используется обработка события submit:

form.addEventListener('submit', (e) => {
  const value = autoNumericInstance.getNumber();

  hiddenInput.value = value;
});

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

Delegation и динамические элементы

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

Поскольку AutoNumeric инициализируется на конкретных элементах, важно синхронизировать создание экземпляров с моментом добавления DOM-узла.

Пример делегирования:

document.addEventListener('input', (event) => {
  if (event.target.matches('.money-input')) {
    const instance = AutoNumeric.getAutoNumericElement(event.target);
    const value = instance.getNumber();
  }
});

Взаимодействие с пользовательскими событиями

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

Часто используется комбинация:

  • input — для реактивных обновлений;
  • blur — для финальной нормализации;
  • change — для фиксации результата.

Особенности работы с value setter’ами

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

Корректный подход:

autoNumericInstance.set(12345.67);

После этого DOM и внутреннее состояние синхронизируются, а события генерируются в соответствии с логикой библиотеки.

Совмещение с валидацией через события

Интеграция со стандартными событиями часто используется для построения системы валидации в реальном времени.

Пример:

input.addEventListener('input', () => {
  const value = autoNumericInstance.getNumber();

  if (value < 0) {
    input.classList.add('error');
  } else {
    input.classList.remove('error');
  }
});

В этом случае важно учитывать, что значение всегда должно получаться через API библиотеки, а не через event.target.value, если требуется числовая точность.

Контроль частоты событий

Из-за высокой частоты срабатывания input в сочетании с перерасчётами AutoNumeric часто требуется ограничение частоты обработки событий.

Применяются стандартные техники:

  • debounce для задержки обработки;
  • throttle для ограничения частоты.
let timeout;

input.addEventListener('input', () => {
  clearTimeout(timeout);

  timeout = setTimeout(() => {
    const value = autoNumericInstance.getNumber();
  }, 200);
});

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

Итоговое поведение событийной модели

Интеграция AutoNumeric со стандартными событиями DOM строится вокруг принципа сохранения нативного поведения input-элемента при добавлении промежуточного слоя форматирования. События input, change, focus и blur остаются основными точками входа в пользовательское взаимодействие, однако их обработка требует обязательного учёта разделения между отображаемым и числовым представлением данных, а также контроля программных обновлений значения во избежание рекурсивных вызовов.