В библиотеке Shopify Draggable управление фокусом является важным аспектом для обеспечения доступности и удобства взаимодействия с перетаскиваемыми элементами. Фокус-менеджмент отвечает за то, чтобы элементы, которые могут быть перемещены или изменены, правильно реагировали на клавиатурные события и оставались доступными для пользователей с особыми потребностями.
Каждый элемент в Draggable может находиться в одном из нескольких состояний:
Для корректной работы важно отслеживать эти состояния через события Draggable:
const draggable = new Draggable(document.querySelectorAll('.draggable'), {
draggable: '.item'
});
draggable.on('drag:start', (event) => {
event.source.classList.add('dragging');
});
draggable.on('drag:stop', (event) => {
event.source.classList.remove('dragging');
});
Draggable предоставляет возможность навигации и управления элементами
с помощью клавиатуры. Элементы должны быть
фокусируемыми, обычно это достигается с помощью
атрибута tabindex="0":
<div class="item" tabindex="0">Элемент 1</div>
<div class="item" tabindex="0">Элемент 2</div>
События drag:start и drag:stop могут быть
расширены обработчиками клавиатурных действий:
draggable.on('drag:move', (event) => {
if(event.originalEvent.key === 'ArrowUp') {
// Логика перемещения элемента вверх
} else if(event.originalEvent.key === 'ArrowDown') {
// Логика перемещения элемента вниз
}
});
При добавлении или удалении элементов важно корректно обновлять фокус. Draggable не управляет этим автоматически, поэтому требуется вручную устанавливать фокус на новый или следующий элемент:
function addItem() {
const newItem = document.createElement('div');
newItem.classList.add('item');
newItem.setAttribute('tabindex', '0');
newItem.textContent = 'Новый элемент';
container.appendChild(newItem);
newItem.focus();
}
Удаление элемента также должно корректно смещать фокус:
function removeItem(item) {
const nextFocus = item.nextElementSibling || item.previousElementSibling;
item.remove();
if(nextFocus) nextFocus.focus();
}
Draggable поддерживает множество событий, которые позволяют управлять фокусом:
drag:over – активируется, когда элемент пересекает
границу другой области; можно менять фокус на текущий контейнер.sortable:sorted – применяется при завершении
сортировки; можно установить фокус на перемещённый элемент.droppable:over – используется для элементов, которые
можно сбросить; фокус может автоматически переходить на приёмный
контейнер.Пример:
draggable.on('sortable:sorted', (event) => {
event.newContainer.focus();
});
Для доступности необходимо правильно использовать ARIA-атрибуты:
aria-grabbed="true" – указывает, что элемент выбран для
перетаскивания.aria-dropeffect="move" – обозначает возможное действие
при сбросе элемента.role="listitem" и role="list" –
обеспечивают семантическое соответствие элементам списка.draggable.on('drag:start', (event) => {
event.source.setAttribute('aria-grabbed', 'true');
});
draggable.on('drag:stop', (event) => {
event.source.setAttribute('aria-grabbed', 'false');
});
const draggable = new Draggable(document.querySelectorAll('.draggable'), {
draggable: '.item',
delay: 100,
mirror: {
constrainDimensions: true
}
});
draggable.on('drag:start', (event) => {
event.source.classList.add('dragging');
event.source.setAttribute('aria-grabbed', 'true');
});
draggable.on('drag:stop', (event) => {
event.source.classList.remove('dragging');
event.source.setAttribute('aria-grabbed', 'false');
event.source.focus();
});
draggable.on('sortable:sorted', (event) => {
event.newContainer.focus();
});
Такой подход обеспечивает плавное и предсказуемое управление фокусом при перетаскивании, поддерживает доступность и улучшает пользовательский опыт.
Фокус-менеджмент в Shopify Draggable требует синхронизации состояния элементов, обработки клавиатурных действий и корректного применения ARIA-атрибутов, что делает интерфейс доступным и интуитивно понятным.