Библиотека ally.js предназначена для обеспечения доступности веб-приложений. Одним из ключевых аспектов является управление фокусом и обработка событий клавиатуры и мыши, что особенно важно при реализации модальных диалогов и всплывающих окон.
Клавиша Escape часто используется для закрытия модальных
окон или отмены текущих действий. ally.js предоставляет
удобные методы для отслеживания событий клавиатуры и управления фокусом
после закрытия диалога.
import * as ally from 'ally.js';
const modal = document.querySelector('#modal');
function closeModal() {
modal.style.display = 'none';
ally.query.firstTabbable({context: document.body})?.focus();
}
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
closeModal();
}
});
Ключевые моменты:
ally.query.firstTabbable() позволяет
вернуть фокус на первый доступный интерактивный элемент после закрытия
модального окна.event.key === 'Escape' гарантирует корректную
обработку клавиши во всех современных браузерах.Для закрытия диалога при клике вне его области используется определение контекста через ally.js. Это позволяет точно выявлять элементы, которые находятся «за пределами» модального окна.
function handleOutsideClick(event) {
if (!modal.contains(event.target)) {
closeModal();
}
}
document.addEventListener('click', handleOutsideClick);
Особенности реализации:
Element.contains() обеспечивает проверку
вложенности, определяя, находится ли целевой элемент внутри
диалога.click отслеживается на уровне
document, что позволяет улавливать клики на любом участке
страницы.event.stopPropagation() на внутренних
элементах.Для соблюдения принципов доступности необходимо ограничивать фокус клавиатуры элементами диалога. ally.js предоставляет утилиты для реализации focus trap:
import * as ally from 'ally.js';
const focusTrap = ally.tab.trap({
context: modal,
trapFocus: true,
onDeactivate: () => {
ally.query.firstTabbable({context: document.body})?.focus();
}
});
focusTrap.activate();
Объяснение работы:
ally.tab.trap() создаёт область, в пределах которой
фокус клавиатуры циклически перемещается между интерактивными
элементами.trapFocus: true блокирует выход фокуса за пределы
диалога при нажатии Tab или Shift+Tab.onDeactivate возвращает фокус на элемент, с
которого пользователь начал взаимодействие.Для комплексного управления модальными окнами события
keydown и click объединяются с focus trap:
function openModal() {
modal.style.display = 'block';
focusTrap.activate();
}
function closeModal() {
modal.style.display = 'none';
focusTrap.deactivate();
}
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
closeModal();
}
});
document.addEventListener('click', (event) => {
if (!modal.contains(event.target)) {
closeModal();
}
});
Рекомендации:
Библиотека позволяет реализовать несколько уровней модальных окон и динамические диалоги. Для этого:
click и keydown; лучше использовать
делегирование.ally.query.tabbable({context: modal}) для
динамического обновления списка элементов при изменении
содержимого.Использование ally.js для управления ESC и кликом вне диалога обеспечивает:
Эти инструменты позволяют создавать интерактивные интерфейсы, которые безопасны и удобны для всех пользователей.