Добавление обработчиков событий

Система событий в Awesomplete построена вокруг взаимодействия экземпляра автодополнения и DOM-элемента ввода. Основная идея заключается в том, что библиотека генерирует набор событий на разных этапах жизненного цикла подсказок: от открытия списка до финального выбора значения. Эти события позволяют встраивать дополнительную логику без модификации внутреннего кода библиотеки.

Каждый экземпляр Awesomplete связан с полем ввода и списком подсказок. При изменении состояния компонента происходят следующие ключевые этапы:

  • открытие списка подсказок;
  • обновление выделенного элемента;
  • закрытие списка;
  • выбор элемента;
  • завершение выбора с подстановкой значения.

События генерируются как DOM CustomEvent и могут быть перехвачены через стандартный addEventListener.

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


Подключение обработчиков к элементу ввода

Базовый способ работы с событиями заключается в использовании стандартного механизма DOM:

const input = document.querySelector("#search");
const awesomplete = new Awesomplete(input, {
  list: ["Apple", "Banana", "Cherry", "Date"]
});

input.addEventListener("awesomplete-open", function (event) {
  console.log("Список открыт");
});

input.addEventListener("awesomplete-close", function (event) {
  console.log("Список закрыт");
});

Каждое событие содержит объект event, который может включать дополнительные данные в detail. Однако в большинстве случаев основная логика строится на факте наступления события.


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

awesomplete-open возникает в момент, когда список подсказок становится видимым. Это событие полезно для:

  • аналитики пользовательского поведения;
  • изменения UI состояния;
  • синхронизации с другими компонентами интерфейса.

Пример использования:

input.addEventListener("awesomplete-open", () => {
  document.body.classList.add("autocomplete-active");
});

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


Событие закрытия списка

awesomplete-close вызывается при скрытии списка подсказок. Закрытие может происходить по нескольким причинам:

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

Пример:

input.addEventListener("awesomplete-close", () => {
  document.body.classList.remove("autocomplete-active");
});

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


Событие выделения элемента

awesomplete-highlight срабатывает при изменении текущего выделенного элемента в списке. Оно позволяет отслеживать навигацию пользователя по подсказкам с помощью клавиатуры или мыши.

input.addEventListener("awesomplete-highlight", (event) => {
  console.log("Выделен элемент:", event.text);
});

Типичная задача этого события — предварительный просмотр значения или отображение дополнительной информации о выбранной подсказке.

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

input.addEventListener("awesomplete-highlight", (event) => {
  const preview = document.querySelector("#preview");
  if (event.text) {
    preview.textContent = event.text.label || event.text.value;
  }
});

Событие выбора элемента

awesomplete-select возникает в момент, когда пользователь инициирует выбор элемента, но до фактической подстановки значения в поле ввода. Это важный этап, позволяющий отменить выбор или модифицировать данные.

input.addEventListener("awesomplete-select", (event) => {
  console.log("Выбран элемент:", event.text);
});

Объект event.text обычно содержит структуру вида:

{
  label: "Apple",
  value: "Apple"
}

На этом этапе возможно вмешательство в процесс, включая предотвращение выбора:

input.addEventListener("awesomplete-select", (event) => {
  if (event.text.value === "Banana") {
    event.preventDefault();
  }
});

Подобный механизм используется для реализации ограничений на выбор или фильтрации значений в зависимости от внешних условий.


Событие завершённого выбора

awesomplete-selectcomplete срабатывает после того, как значение уже подставлено в поле ввода. Это финальная стадия обработки выбора.

input.addEventListener("awesomplete-selectcomplete", (event) => {
  console.log("Финальное значение:", input.value);
});

Данное событие используется для:

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

Важно учитывать, что в отличие от awesomplete-select, здесь изменение значения уже завершено, и отменить его невозможно.


Программное управление событиями

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

function onOpen() {
  console.log("Открытие списка");
}

input.addEventListener("awesomplete-open", onOpen);

// Позднее удаление обработчика
input.removeEventListener("awesomplete-open", onOpen);

Такая практика предотвращает утечки памяти и неконтролируемое накопление обработчиков.


Делегирование событий

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

document.body.addEventListener("awesomplete-selectcomplete", (event) => {
  if (event.target.matches(".search-input")) {
    console.log("Выбор в поле поиска:", event.target.value);
  }
});

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


Передача пользовательских данных через события

Хотя Awesomplete предоставляет стандартный набор событий, возможно расширение логики через пользовательские свойства объекта события.

input.addEventListener("awesomplete-open", (event) => {
  event.context = {
    timestamp: Date.now(),
    source: "search-bar"
  };
});

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


Связь событий с жизненным циклом ввода

События Awesomplete тесно связаны с действиями пользователя:

  • ввод символов → обновление списка;
  • появление списка → awesomplete-open;
  • навигация стрелками → awesomplete-highlight;
  • подтверждение выбора → awesomplete-select;
  • подстановка значения → awesomplete-selectcomplete;
  • скрытие списка → awesomplete-close.

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


Использование нескольких обработчиков на одно событие

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

input.addEventListener("awesomplete-open", () => {
  console.log("Логирование открытия");
});

input.addEventListener("awesomplete-open", () => {
  document.querySelector("#hint").style.display = "block";
});

Порядок выполнения определяется порядком регистрации обработчиков.


Интеграция событий в архитектуру приложения

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

  • обновления состояния стора;
  • взаимодействия с API;
  • синхронизации компонентов интерфейса;
  • построения аналитики пользовательских действий.

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