Навигация между полями формы

Библиотека ally.js предназначена для управления фокусом и улучшения доступности веб-интерфейсов. Одной из ключевых её возможностей является упрощение навигации между элементами формы, особенно в сложных интерфейсах с множеством интерактивных компонентов.


Выбор элементов для навигации

Для управления фокусом используется функция tabster и вспомогательные методы библиотеки:

const focusableElements = ally.query.tabbable({
  context: document.querySelector('#form-container')
});
  • context — корневой элемент, внутри которого выполняется поиск.
  • tabbable — возвращает только элементы, доступные для табуляции (инпуты, кнопки, ссылки с href).
  • Возвращается массив DOM-элементов в порядке естественной табуляции.

Метод tabbable учитывает атрибуты disabled, aria-hidden, tabindex=-1, что позволяет исключать недоступные для фокуса элементы.


Перемещение фокуса программно

Для перемещения фокуса между полями формы используется ally.focus:

ally.focus.next({ context: document.querySelector('#form-container') });
ally.focus.previous({ context: document.querySelector('#form-container') });
  • next — перемещает фокус на следующий tabbable-элемент.
  • previous — перемещает фокус на предыдущий tabbable-элемент.
  • Параметр context ограничивает область поиска элементов.

Можно также задавать фильтры по селекторам:

ally.focus.next({
  context: document.querySelector('#form-container'),
  filter: '[data-required]'
});

Фокус переместится только на элементы, имеющие атрибут data-required.


Настройка поведения при циклической навигации

Библиотека позволяет создавать циклическую навигацию, возвращая фокус к первому элементу после последнего:

const inputs = ally.query.tabbable({ context: form });
let currentIndex = 0;

form.addEventListener('keydown', (event) => {
  if (event.key === 'Tab') {
    event.preventDefault();
    currentIndex = (currentIndex + (event.shiftKey ? -1 : 1) + inputs.length) % inputs.length;
    inputs[currentIndex].focus();
  }
});
  • Используется event.shiftKey для определения направления перемещения.
  • Модульная арифметика обеспечивает цикличность.
  • Подобная реализация позволяет гибко управлять фокусом в кастомных формах без изменения DOM.

Управление фокусом при динамическом изменении DOM

Для форм, где элементы добавляются или удаляются динамически, ally.js предоставляет методы для пересчёта tabbable-элементов:

const refreshFocusable = () => {
  return ally.query.tabbable({ context: document.querySelector('#form-container') });
};

let focusableElements = refreshFocusable();

// После добавления нового поля
document.querySelector('#add-field').addEventListener('click', () => {
  focusableElements = refreshFocusable();
});
  • ally.query.tabbable динамически сканирует DOM.
  • Пересчёт обеспечивает корректную работу навигации даже при изменении структуры формы.

Применение атрибутов ARIA

Ally.js корректно учитывает атрибуты aria-disabled, aria-hidden, что важно для обеспечения доступности:

<input type="text" aria-disabled="true" />
<input type="text" aria-hidden="true" />
  • Такие элементы не попадут в список tabbable, даже если они визуально видимы.
  • Совмещение ally.js и ARIA гарантирует, что пользователи с ассистивными технологиями получат предсказуемое поведение фокуса.

Группировка и приоритет фокуса

Для сложных форм возможно задание приоритета полей с помощью tabindex:

<input type="text" tabindex="2" />
<input type="text" tabindex="1" />
<input type="text" tabindex="3" />

Ally.js учитывает tabindex при вычислении порядка навигации. Элементы с положительным tabindex получают приоритет над элементами с tabindex="0".

Дополнительно можно объединять поля в группы и навигировать внутри группы:

const group = document.querySelectorAll('.form-section input');
ally.focus.next({ context: group[0].closest('.form-section') });
  • Это упрощает управление фокусом внутри логических блоков формы.

Обработка специальных кейсов

  1. Модальные окна: при открытии модального окна фокус можно закрепить внутри него.

    ally.maintain.disabled({ context: modal });
    • Элементы вне модального окна временно недоступны для табуляции.
  2. Скрытые вкладки: поля на неактивной вкладке исключаются из tabbable.

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


Эти возможности ally.js позволяют создавать формы с интуитивной и доступной навигацией, обеспечивая корректную работу клавиатурных пользователей и ассистивных технологий. Правильное применение функций tabbable, focus.next, focus.previous и управление контекстом позволяет строить сложные интерактивные формы с гибкой логикой перемещения фокуса.