ARIA (Accessible Rich Internet Applications) — это набор атрибутов, предназначенных для повышения доступности веб-приложений. Dragula, как библиотека для реализации drag-and-drop интерфейсов, требует особого внимания к корректной работе с ARIA, чтобы элементы, которые перетаскиваются, были доступны для пользователей вспомогательных технологий, таких как экранные читалки.
Каждый элемент, который может быть перемещён с помощью Dragula,
должен иметь правильно заданную роль. Наиболее
подходящей является роль listitem в составе контейнера с
ролью list:
<div role="list" id="container">
<div role="listitem" draggable="true">Элемент 1</div>
<div role="listitem" draggable="true">Элемент 2</div>
</div>
Ключевые моменты:
draggable="true" позволяет браузеру распознавать
элемент как интерактивный для drag-and-drop.list и listitem обеспечивают
семантическую структуру, понятную вспомогательным технологиям.aria-grabbed.Атрибут aria-grabbed отражает текущее состояние
элемента:
aria-grabbed="true" — элемент выбран для
перетаскивания.aria-grabbed="false" — элемент не выбран.В Dragula это можно реализовать через прослушку событий
drag и dragend:
dragula([document.getElementById('container')])
.on('drag', function (el) {
el.setAttribute('aria-grabbed', 'true');
})
.on('dragend', function (el) {
el.setAttribute('aria-grabbed', 'false');
});
Для поддержания корректного взаимодействия с экранными читалками
важно обновлять атрибут aria-dropeffect у контейнеров. Этот
атрибут указывает, какие действия допустимы при перетаскивании в данный
контейнер:
var containers = [document.getElementById('container')];
containers.forEach(function(container) {
container.setAttribute('aria-dropeffect', 'move');
});
move — элемент будет перемещён.copy — элемент будет скопирован.none — перетаскивание в этот контейнер запрещено.При Dragula необходимо динамически изменять
aria-dropeffect в зависимости от текущей операции.
Например, при наведении перетаскиваемого элемента на контейнер:
dragula(containers)
.on('over', function (el, container) {
container.setAttribute('aria-dropeffect', 'move');
})
.on('out', function (el, container) {
container.setAttribute('aria-dropeffect', 'none');
});
ARIA-атрибуты позволяют организовать не только визуальное, но и клавиатурное взаимодействие с элементами Dragula. Для этого:
tabindex="0").Пример:
<div role="list" id="container">
<div role="listitem" tabindex="0" aria-grabbed="false">Элемент 1</div>
</div>
С помощью обработчика keydown можно изменять
aria-grabbed и aria-dropeffect для имитации
перетаскивания:
document.querySelectorAll('[role="listitem"]').forEach(function(el) {
el.addEventListener('keydown', function(e) {
if (e.key === " " || e.key === "Enter") {
var grabbed = el.getAttribute('aria-grabbed') === 'true';
el.setAttribute('aria-grabbed', grabbed ? 'false' : 'true');
}
});
});
После завершения перетаскивания важно обновлять ARIA-структуру, чтобы экранные читалки корректно озвучивали новую последовательность элементов:
dragula(containers).on('drop', function (el, target, source, sibling) {
Array.from(target.children).forEach(function(child, index) {
child.setAttribute('aria-posinset', index + 1);
child.setAttribute('aria-setsize', target.children.length);
});
});
aria-posinset — позиция элемента в списке.aria-setsize — общее количество элементов в
контейнере.Dragula часто используется с контейнерами, которые создаются динамически. В этом случае:
Пример динамического добавления элемента:
var container = document.getElementById('container');
var newItem = document.createElement('div');
newItem.setAttribute('role', 'listitem');
newItem.setAttribute('draggable', 'true');
newItem.setAttribute('aria-grabbed', 'false');
newItem.textContent = 'Новый элемент';
container.appendChild(newItem);
// Обновление Dragula
dragula([container]);
Для более точного описания состояния drag-and-drop можно использовать:
aria-label — описание элемента для экранного
читалки.aria-describedby — ссылка на элемент с дополнительной
информацией.aria-live="polite" — динамическое уведомление о
перемещении элементов.var liveRegion = document.createElement('div');
liveRegion.setAttribute('aria-live', 'polite');
liveRegion.style.position = 'absolute';
liveRegion.style.left = '-9999px';
document.body.appendChild(liveRegion);
dragula([container])
.on('drop', function (el, target) {
liveRegion.textContent = `${el.textContent} перемещён в новый контейнер`;
});
aria-*.aria-grabbed и
aria-dropeffect для корректной работы со вспомогательными
технологиями.ARIA-атрибуты в Dragula обеспечивают полноценную доступность интерфейса, позволяя пользователям с ограниченными возможностями видеть и управлять элементами списка наравне с мышью. Корректная реализация этих атрибутов превращает простой drag-and-drop в полностью инклюзивное взаимодействие.