В библиотеке AutoNumeric обработка событий строится вокруг
расширенной модели взаимодействия с DOM-элементами, где форматирование
числового ввода и синхронизация состояния происходят не только через
стандартные события input, change,
blur, но и через внутренние механизмы, позволяющие
отслеживать жизненный цикл значения и его преобразований.
Ключевая особенность заключается в том, что библиотека не заменяет нативную событийную модель, а расширяет её, добавляя слой абстракции над форматированием, парсингом и валидацией.
При работе с числовыми полями можно выделить несколько групп событий:
input — изменение значения в процессе вводаchange — фиксация значения после потери фокусаfocus — активация поля вводаblur — потеря фокусаkeydown, keyup — обработка клавиатурного
вводаAutoNumeric перехватывает ввод и изменяет поведение стандартных событий, добавляя этапы:
В зависимости от конфигурации и версии, могут использоваться события уровня API:
Обработчики в AutoNumeric можно разделить на три уровня:
Прямое навешивание обработчиков на input-элемент:
element.addEventListener('input', handler);
element.addEventListener('blur', handler);
Этот слой отвечает за первичный захват пользовательского ввода.
AutoNumeric перехватывает события и применяет внутренние преобразования:
Колбэки, передаваемые через конфигурацию:
AutoNumeric.set(input, {
onChange: (currentValue, element) => {
console.log(currentValue);
}
});
AutoNumeric предоставляет механизм привязки логики через конфигурационный объект. Наиболее важные параметры:
Срабатывает при попытке вставки некорректного значения.
AutoNumeric.set(input, {
onInvalidPaste: (clipboardData, element) => {
return false;
}
});
Возвращаемое значение позволяет:
Позволяют управлять состоянием отображения:
AutoNumeric.set(input, {
onFocus: (event, element) => {
element.classList.add('active');
},
onBlur: (event, element) => {
element.classList.remove('active');
}
});
Используются для:
Срабатывает при изменении уже нормализованного значения:
AutoNumeric.set(input, {
onChange: (value, element) => {
updateModel(value);
}
});
Особенность заключается в том, что значение уже приведено к числовому виду или строковому формату, определённому конфигурацией.
При создании экземпляра AutoNumeric появляется возможность управлять значением программно, что также может триггерить обработчики.
const an = new AutoNumeric(input, {
decimalPlaces: 2
});
an.set(1234.56);
Изменение значения через set() может вызывать цепочку
событий:
Обработка клавиатурного ввода является критическим компонентом системы:
AutoNumeric.set(input, {
onKeyDown: (event, element) => {
if (event.key === '-') {
return true;
}
return false;
}
});
Механизм позволяет:
Несмотря на наличие встроенных колбэков, часто используется прямое подключение событий:
const an = new AutoNumeric(input);
input.addEventListener('input', () => {
const rawValue = an.getNumericString();
console.log(rawValue);
});
Такой подход применяется для:
AutoNumeric влияет на порядок выполнения событий, внедряясь между фазами:
Особое внимание требуется при работе с input, так как
значение может изменяться несколько раз в пределах одного события.
При интеграции с другими библиотеками (React, Vue, Angular) возникают ситуации дублирования событий.
Распространённые проблемы:
input при controlled компонентахТиповой способ минимизации конфликтов:
AutoNumeric.set(input, {
watchExternalChanges: true,
modifyValueOnWheel: false
});
Также применяется ручное подавление событий:
let internalUpdate = false;
input.addEventListener('input', (e) => {
if (internalUpdate) return;
const value = an.getNumericString();
sync(value);
});
Хотя библиотека не всегда генерирует полноценные CustomEvent, возможно создание собственной системы поверх AutoNumeric:
function emitValueChange(element, value) {
element.dispatchEvent(new CustomEvent('autonumeric:change', {
detail: { value }
}));
}
Используется для:
Событие вставки требует отдельной логики, так как данные приходят без поэтапного ввода:
AutoNumeric.set(input, {
onInvalidPaste: (clipboard, element) => {
const cleaned = clipboard.replace(/[^\d.-]/g, '');
return cleaned;
}
});
Типичная цепочка:
При работе с динамически создаваемыми элементами применяется делегирование:
document.addEventListener('input', (e) => {
if (e.target.matches('.auto')) {
const instance = AutoNumeric.getAutoNumericElement(e.target);
console.log(instance.getNumber());
}
});
Подход полезен при:
При удалении элементов важно корректно освобождать события:
const an = new AutoNumeric(input);
an.wipe();
input.removeEventListener('input', handler);
Игнорирование очистки приводит к:
На практике используются несколько устойчивых подходов:
Все изменения проходят через единый обработчик:
onChange: (value) => store.update(value);
Разделение:
Обёртка над AutoNumeric:
function createNumericField(input) {
const an = new AutoNumeric(input);
input.addEventListener('input', () => {
emit(an.getNumericString());
});
return an;
}
Изменение значения через API не всегда эквивалентно пользовательскому вводу. Это требует различения источников событий:
inputset() → внутреннее обновлениеupd ate() → синхронизация состоянияКонтроль источника позволяет избежать циклических обновлений:
let source = 'user';
an.se t(100);
source = 'system';
При высокой частоте ввода критично:
let timeout;
input.addEventListener('input', () => {
clearTimeout(timeout);
timeout = setTimeout(() => {
sync(an.getNumericString());
}, 100);
});
Оптимизация особенно важна в больших формах и таблицах с множественными инстансами AutoNumeric.