Отмена действий по умолчанию

Поведение автодополнения в браузере тесно связано с нативными событиями DOM. В контексте Awesomplete ключевая сложность возникает там, где стандартные действия элементов формы начинают конфликтовать с логикой выбора подсказок. Любое поле ввода по умолчанию обрабатывает клавиши Enter, Tab, стрелки, а также инициирует отправку формы. Awesomplete накладывает поверх этого собственную модель взаимодействия, и без управления стандартными действиями возникает расхождение между ожидаемым и фактическим поведением интерфейса.

Базовый механизм отмены стандартного поведения

Основной инструмент управления стандартными действиями — event.preventDefault(). В связке с Awesomplete он применяется в обработчиках клавиатурных событий и событий выбора. Типичный сценарий связан с тем, что при нажатии Enter браузер пытается отправить форму, тогда как логика автодополнения предполагает выбор активного элемента списка.

input.addEventListener("keydown", function (event) {
    if (event.key === "Enter") {
        if (awesomplete.opened) {
            event.preventDefault();
        }
    }
});

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

Конфликт Tab и логики автодополнения

Клавиша Tab традиционно переводит фокус на следующий элемент формы. Awesomplete часто использует Tab для подтверждения текущего выбора. Это создаёт прямой конфликт: либо теряется навигация по форме, либо ломается UX автодополнения.

Для решения применяется условная отмена действия:

input.addEventListener("keydown", function (event) {
    if (event.key === "Tab" && awesomplete.opened) {
        event.preventDefault();
    }
});

После отмены стандартного поведения управление передаётся логике библиотеки, которая завершает выбор активного элемента.

Управление событием выбора

Awesomplete предоставляет события уровня компонента, включая awesomplete-select и awesomplete-selectcomplete. Они позволяют вмешиваться в процесс до и после вставки значения в поле ввода.

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

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

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

input.addEventListener("awesomplete-select", function (event) {
    event.preventDefault();
    input.value = event.text.label.toUpperCase();
});

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

Различие preventDefault и stopPropagation

В работе с Awesomplete часто смешиваются два механизма управления событиями:

  • preventDefault() — отменяет стандартное поведение браузера
  • stopPropagation() — блокирует всплытие события по DOM-дереву

Awesomplete в большинстве сценариев зависит именно от preventDefault(). Использование stopPropagation() без отмены действия не предотвращает, например, отправку формы или потерю фокуса.

input.addEventListener("keydown", function (event) {
    if (event.key === "Enter") {
        event.stopPropagation();
    }
});

Такой код не остановит отправку формы, если она инициируется самим браузером. Поэтому при интеграции с автодополнением приоритет всегда остаётся за preventDefault().

Отмена отправки формы при активном списке

Один из наиболее частых сценариев — предотвращение submit при открытом списке подсказок. Поведение по умолчанию приводит к тому, что Enter одновременно выбирает элемент и отправляет форму.

Корректная обработка требует проверки состояния компонента:

form.addEventListener("submit", function (event) {
    if (awesomplete.opened) {
        event.preventDefault();
    }
});

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

Перехват мышиного выбора

Клик по элементу списка в Awesomplete также инициирует стандартную цепочку событий: mousedown → click → selection. В некоторых интерфейсах требуется предотвратить потерю фокуса или изменить поведение клика.

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

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

Контроль поведения через keydown до Awesomplete

Awesomplete обрабатывает клавиши на уровне keydown. Если требуется полностью переопределить поведение клавиши, обработчик должен срабатывать до логики библиотеки.

input.addEventListener("keydown", function (event) {
    if (!awesomplete.opened) return;

    if (event.key === "ArrowDown") {
        event.preventDefault();
        awesomplete.next();
    }

    if (event.key === "ArrowUp") {
        event.preventDefault();
        awesomplete.previous();
    }
});

Здесь отменяется стандартное перемещение курсора внутри input, а управление передаётся навигации по списку подсказок.

Поведение при IME и композиции текста

Особый случай — ввод с использованием IME (Input Method Editor), например, при наборе иероглифов. Во время compositionstart и compositionend стандартная логика клавиш может работать некорректно.

let composing = false;

input.addEventListener("compositionstart", () => {
    composing = true;
});

input.addEventListener("compositionend", () => {
    composing = false;
});

И дальнейшая защита обработчиков:

input.addEventListener("keydown", function (event) {
    if (composing) return;

    if (event.key === "Enter" && awesomplete.opened) {
        event.preventDefault();
    }
});

Без такого контроля автодополнение может перехватывать клавиши в момент, когда вводимое значение ещё не завершено.

Переопределение логики вставки значения

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

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

Далее возможно ручное управление состоянием:

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

    const data = event.text;
    input.value = `${data.value}:${data.label}`;
});

Такой подход применяется при работе с идентификаторами, где отображаемое значение и фактическое значение различаются.

Управление фокусом после отмены действия

Отмена стандартного поведения часто приводит к необходимости вручную управлять фокусом. Например, при блокировке Tab требуется перенаправление фокуса на следующий элемент:

input.addEventListener("keydown", function (event) {
    if (event.key === "Tab" && awesomplete.opened) {
        event.preventDefault();
        const next = form.querySelector("input, button, select");
        if (next) next.focus();
    }
});

Без такого контроля интерфейс теряет предсказуемую навигацию.

Согласование состояния списка и DOM

Отмена действий по умолчанию тесно связана с состоянием выпадающего списка. Проверка awesomplete.opened становится ключевым условием, поскольку одинаковые клавиши должны вести себя по-разному в зависимости от контекста:

  • список закрыт → стандартное поведение браузера
  • список открыт → управление переходит Awesomplete

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

input.addEventListener("keydown", function (event) {
    if (!awesomplete.opened) return;

    if (event.key === "Enter") {
        event.preventDefault();
        awesomplete.select();
    }
});

Итоговая модель контроля поведения

Корректная интеграция Awesomplete требует комбинирования нескольких уровней управления событиями: отмены стандартного поведения, перехвата событий библиотеки и ручного управления состоянием интерфейса. Основная логика строится вокруг точечного применения preventDefault() только в тех случаях, когда поведение браузера конфликтует с логикой автодополнения, а не как универсальная блокировка всех действий.