Библиотека AutoNumeric в JavaScript строится вокруг расширяемой событийной модели, в которой любое изменение значения поля, форматирование или вмешательство пользователя может быть перехвачено и обработано через набор встроенных событий и пользовательских обработчиков. Такая архитектура позволяет не только реагировать на изменения данных, но и модифицировать поведение форматирования на лету, внедрять валидацию, синхронизацию с внешними системами и реализовывать собственные правила взаимодействия с числовыми полями.
Пользовательские обработчики в контексте AutoNumeric представляют собой функции, которые подключаются к жизненному циклу экземпляра и получают контроль над ключевыми моментами: ввод данных, потеря/получение фокуса, изменение «сырого» значения, попытка вставки некорректного текста, а также финальное форматирование отображаемого значения.
Каждый экземпляр AutoNumeric инкапсулирует input-элемент и управляет его состоянием через внутренний слой нормализации данных. При этом библиотека генерирует набор событий DOM и собственных событий, расширяющих стандартную модель браузера.
Основные уровни обработки:
На каждом из этих этапов может быть внедрён пользовательский обработчик, влияющий либо на поток данных, либо на побочные эффекты (логирование, синхронизация, валидация).
AutoNumeric позволяет передавать функции-обработчики при инициализации экземпляра через объект конфигурации. Такой подход обеспечивает декларативное подключение логики.
const anElement = new AutoNumeric('#price', {
onFocus: (event) => {
console.log('Фокус установлен');
},
onBlur: (event) => {
console.log('Фокус потерян');
},
onChange: (event) => {
console.log('Значение изменено');
}
});
Каждый обработчик получает стандартный DOM Event, а также доступ к связанному элементу input. Однако важной особенностью является то, что значение, доступное в DOM, может быть уже отформатировано, поэтому для работы с числом используется API экземпляра.
Для корректной работы с числовыми данными внутри пользовательских функций применяется доступ к экземпляру AutoNumeric.
const anElement = new AutoNumeric('#price', {
onChange: (event) => {
const numericValue = anElement.getNumber();
console.log(numericValue);
}
});
Метод getNumber() возвращает нормализованное числовое
значение без форматирования. Это ключевой момент при построении
бизнес-логики поверх AutoNumeric, так как DOM-значение всегда является
строкой с локализованным форматом.
Одним из наиболее важных событий является изменение внутреннего значения, не зависящего от визуального представления. Это значение называется raw value и обновляется при любом валидном вводе.
Пользовательский обработчик может быть подключён для отслеживания таких изменений:
const anElement = new AutoNumeric('#price', {
onChange: () => {
const raw = anElement.getNumericString();
console.log('Raw value:', raw);
}
});
Метод getNumericString() возвращает строковое
представление числа без форматирования, что важно для сериализации и
передачи на сервер.
Помимо встроенных callback-параметров, AutoNumeric полностью
совместим с нативной системой событий DOM. Это позволяет использовать
стандартный механизм addEventListener.
const input = document.querySelector('#price');
const anElement = new AutoNumeric(input);
input.addEventListener('input', (event) => {
console.log('Input событие:', event.target.value);
});
Такой подход применяется, когда требуется интеграция с внешними библиотеками, которые не поддерживают конфигурационные callback-и AutoNumeric.
AutoNumeric предоставляет механизм обработки некорректных действий пользователя, таких как вставка недопустимых символов или попытка ввода формата, не соответствующего конфигурации.
const anElement = new AutoNumeric('#price', {
onInvalidPaste: (event) => {
console.log('Попытка вставки некорректных данных');
},
onInvalidEvent: (event) => {
console.log('Некорректное действие пользователя');
}
});
Такие обработчики используются для реализации строгих правил ввода, аудита пользовательских действий или отображения кастомных уведомлений.
Пользовательские обработчики могут не только реагировать на события,
но и изменять поток выполнения логики. В некоторых сценариях
используется предотвращение стандартного поведения через
event.preventDefault().
const anElement = new AutoNumeric('#price', {
onFocus: (event) => {
if (someCondition) {
event.preventDefault();
}
}
});
Это позволяет блокировать фокусировку, отменять вставку или ограничивать ввод при определённых условиях.
При использовании внешних функций важно учитывать контекст исполнения. Потеря контекста приводит к невозможности доступа к методам экземпляра. Для решения применяется явное связывание.
function handleChange(event) {
const value = this.getNumber();
console.log(value);
}
const anElement = new AutoNumeric('#price', {
onChange: handleChange.bind(anElement)
});
Такой подход делает возможным переиспользование обработчиков между разными экземплярами.
В сложных интерфейсах часто используется подход делегирования, при котором один обработчик обслуживает множество полей AutoNumeric.
document.body.addEventListener('change', (event) => {
if (event.target.matches('.numeric')) {
const instance = AutoNumeric.getAutoNumericElement(event.target);
console.log(instance.getNumber());
}
});
Делегирование позволяет минимизировать количество обработчиков и упрощает управление динамически создаваемыми элементами.
Поверх стандартной модели событий может быть построен промежуточный слой обработки (middleware), который последовательно модифицирует значение до его применения.
const middlewares = [
(value) => value.replace(',', '.'),
(value) => value.trim(),
(value) => Number(value) * 2
];
const anElement = new AutoNumeric('#price', {
onBeforeFormat: (value) => {
return middlewares.reduce((acc, fn) => fn(acc), value);
}
});
Такой подход используется для сложной бизнес-логики, где значение проходит несколько этапов трансформации.
Экземпляр AutoNumeric проходит несколько фаз:
На каждой фазе могут быть подключены пользовательские обработчики, особенно на этапе инициализации и разрушения.
const anElement = new AutoNumeric('#price', {
onInitialized: () => {
console.log('Экземпляр создан');
},
onDestroy: () => {
console.log('Экземпляр уничтожен');
}
});
Часто обработчики используются для синхронизации с сервером или состоянием приложения. В таких случаях важно учитывать частоту вызовов и возможность избыточных обновлений.
let timeout;
const anElement = new AutoNumeric('#price', {
onChange: () => {
clearTimeout(timeout);
timeout = setTimeout(() => {
sendToServer(anElement.getNumericString());
}, 300);
}
});
Данный подход предотвращает частые сетевые запросы и стабилизирует нагрузку.
При использовании нескольких обработчиков на одном элементе может возникнуть конфликт логики. Для управления порядком выполнения применяется явное разделение ответственности:
Разделение позволяет избежать ситуации, при которой один обработчик изменяет состояние, ожидаемое другим.
const anElement = new AutoNumeric('#price', {
onChange: () => validate(anElement.getNumber()),
onBlur: () => save(anElement.getNumericString())
});
Такая структура снижает связность логики и повышает предсказуемость поведения.
Для крупных приложений часто создаётся абстракция поверх AutoNumeric, инкапсулирующая обработчики и предоставляющая единый интерфейс.
class NumericField {
constructor(selector) {
this.instance = new AutoNumeric(selector, {
onChange: this.handleChange.bind(this)
});
}
handleChange() {
const value = this.instance.getNumber();
this.sync(value);
}
sync(value) {
console.log('Sync:', value);
}
}
Такой подход позволяет централизовать обработку событий и упростить сопровождение кода.
Пользовательские обработчики в AutoNumeric формируют слой адаптации между низкоуровневым управлением DOM и бизнес-логикой приложения. Их корректная организация включает:
Такая структура позволяет строить устойчивые интерфейсы ввода числовых данных с предсказуемым поведением даже в сложных динамических приложениях.