Обзор системы событий

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

Awesomplete работает с двумя уровнями событий:

  • DOM-события элемента input (нативные события браузера)
  • кастомные события Awesomplete, создаваемые через CustomEvent

Каждое значимое действие внутри библиотеки приводит к вызову dispatchEvent на связанном input-элементе. Таким образом, внешний код может подписываться на события стандартным способом:

input.addEventListener("awesomplete-select", function (event) {
    console.log(event.detail);
});

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

Основные события жизненного цикла

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

awesomplete-open

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

  • вводе символов, соответствующих хотя бы одному результату
  • программном вызове открытия списка
  • повторной активации после изменения значения input
input.addEventListener("awesomplete-open", function () {
    console.log("Список открыт");
});

Событие не содержит дополнительных данных в event.detail, так как само по себе фиксирует факт изменения состояния интерфейса.

awesomplete-close

Событие awesomplete-close вызывается при закрытии выпадающего списка. Причины закрытия могут быть различными:

  • выбор элемента
  • очистка input
  • потеря фокуса
  • отсутствие совпадений
input.addEventListener("awesomplete-close", function () {
    console.log("Список закрыт");
});

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

awesomplete-highlight

Событие awesomplete-highlight возникает при изменении активного (подсвеченного) элемента списка. Подсветка может изменяться:

  • при навигации клавишами ↑ ↓
  • при движении мыши
  • при автоматическом выборе первого элемента
input.addEventListener("awesomplete-highlight", function (event) {
    console.log(event.text);
});

event.text содержит объект с данными текущего элемента списка, включая его значение и отображаемый текст.

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

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

awesomplete-select

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

input.addEventListener("awesomplete-select", function (event) {
    console.log("Выбор инициирован:", event.text);
});

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

input.addEventListener("awesomplete-select", function (event) {
    event.preventDefault();
});

Вызов preventDefault() останавливает дальнейшее выполнение стандартного механизма подстановки значения.

awesomplete-selectcomplete

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

input.addEventListener("awesomplete-selectcomplete", function (event) {
    console.log("Выбрано значение:", input.value);
});

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

Структура объекта event.detail

Во многих событиях Awesomplete передаёт дополнительную информацию через event.detail. Обычно это объект с полем text, которое представляет выбранный или подсвеченный элемент.

Типичная структура:

{
    text: {
        label: "Отображаемый текст",
        value: "Фактическое значение"
    }
}

Разделение label и value позволяет использовать разные представления данных для интерфейса и логики приложения.

Программные события и кастомные триггеры

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

Пример имитации события открытия:

input.dispatchEvent(new CustomEvent("awesomplete-open"));

Такой подход используется в случаях, когда необходимо синхронизировать Awesomplete с внешними UI-компонентами, например с React или Vue-обёртками.

Связь событий с колбэками экземпляра

Помимо событий DOM, Awesomplete поддерживает набор колбэков, которые задаются при инициализации:

  • open
  • close
  • select
  • replace
  • filter
  • sort
new Awesomplete(input, {
    filter: function (text, input) {
        return text.indexOf(input) === 0;
    },
    sort: function (a, b) {
        return a.length - b.length;
    },
    replace: function (text) {
        this.input.value = text.value;
    }
});

Колбэки и события работают на разных уровнях. Колбэк изменяет поведение алгоритма, тогда как событие фиксирует факт произошедшего действия. Это разделение важно для построения расширяемой архитектуры.

Порядок срабатывания событий

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

  1. awesomplete-select
  2. изменение значения input (если не отменено)
  3. awesomplete-selectcomplete
  4. awesomplete-close

При открытии списка:

  1. awesomplete-open

При изменении подсветки:

  • awesomplete-highlight вызывается многократно при каждом изменении активного элемента

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

Особенности распространения событий

События Awesomplete диспатчатся непосредственно на DOM-элемент input, без использования глобального event bus. Это означает:

  • события локализованы в пределах конкретного поля ввода
  • несколько экземпляров Awesomplete не конфликтуют между собой
  • обработчики можно навешивать независимо для каждого input

Внутренне используется стандартный механизм:

input.dispatchEvent(new CustomEvent(name, { detail }));

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

Событийная модель Awesomplete позволяет строить сложные сценарии поведения интерфейса без вмешательства в логику библиотеки. Например:

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

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