SortableJS — это мощная библиотека для реализации перетаскивания элементов (drag-and-drop) в веб-приложениях. Она работает с любыми HTML-элементами, поддерживает сортировку списков и сеток, позволяет объединять несколько контейнеров и полностью настраивается через опции и события.
Инициализация Sortable:
import Sortable from 'sortablejs';
const list = document.getElementById('sortable-list');
const sortable = Sortable.create(list, {
animation: 150,
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen'
});
animation — плавность перемещения, выражается в
миллисекундах.ghostClass — CSS-класс для элемента, который визуально
перемещается.chosenClass — класс для выбранного элемента.Каждый элемент внутри контейнера может быть перетаскиваемым. По
умолчанию библиотека работает с <li> и
<div> внутри родительского контейнера.
SortableJS поддерживает фокус и работу с клавиатурой через расширение
MultiDrag и события DOM. Фокусировка элементов играет
ключевую роль для доступности и корректного управления перемещением
через клавиатуру.
const sortable = Sortable.create(list, {
multiDrag: true,
selectedClass: 'selected',
store: {
get: () => JSON.parse(localStorage.getItem('order') || '[]'),
set: (sortable) => {
const order = sortable.toArray();
localStorage.setItem('order', JSON.stringify(order));
}
}
});
multiDrag — позволяет выбирать несколько элементов для
перемещения.selectedClass — CSS-класс выделенных элементов.store — объект для сохранения и восстановления порядка
элементов.Фокусировка реализуется стандартными HTML-атрибутами:
<li tabindex="0">Элемент 1</li>
<li tabindex="0">Элемент 2</li>
<li tabindex="0">Элемент 3</li>
tabindex="0" делает элемент доступным для табуляции.
Когда элемент получает фокус, события focus и
blur могут использоваться для изменения визуального
состояния или активации клавиатурных обработчиков.
Табуляция позволяет переходить между элементами с помощью клавиши
Tab. Для интеграции с SortableJS необходимо отслеживать
фокус и обрабатывать перемещение через стрелки:
list.addEventListener('keydown', (event) => {
const focused = document.activeElement;
if (!focused || !list.contains(focused)) return;
switch (event.key) {
case 'ArrowUp':
if (focused.previousElementSibling) focused.previousElementSibling.focus();
break;
case 'ArrowDown':
if (focused.nextElementSibling) focused.nextElementSibling.focus();
break;
case 'Enter':
sortable.option('disabled', !sortable.option('disabled'));
break;
}
});
Enter может активировать режим перетаскивания или
блокировать сортировку.SortableJS позволяет объединять несколько списков в один
интерактивный блок. Для корректного управления фокусом при
перетаскивании между контейнерами необходимо использовать событие
onAdd:
const container1 = document.getElementById('container1');
const container2 = document.getElementById('container2');
Sortable.create(container1, {
group: 'shared',
animation: 150,
onAdd: (evt) => {
evt.item.focus();
}
});
Sortable.create(container2, {
group: 'shared',
animation: 150,
onAdd: (evt) => {
evt.item.focus();
}
});
group — объединяет списки для возможности
перетаскивания между ними.onAdd — событие, вызываемое после добавления элемента в
другой контейнер. Вызов focus() на элементе обеспечивает
сохранение клавиатурной навигации.Для повышения удобства использования важна визуальная обратная связь:
.sortable-chosen {
outline: 2px solid #007BFF;
}
.sortable-ghost {
opacity: 0.5;
}
sortable-chosen — элемент, который в фокусе или
выбран.sortable-ghost — полупрозрачное отображение
перетаскиваемого элемента.SortableJS предоставляет богатый набор событий:
onStart — начало перетаскивания.onEnd — завершение перемещения.onMove — проверка возможности перемещения.onSort — завершение сортировки внутри контейнера.События можно использовать для синхронизации состояния интерфейса с данными приложения, например, обновления хранилища или уведомления пользователя о изменении порядка элементов.
Для поддержания доступности:
tabindex для всех интерактивных
элементов.store.Enter для управления
фокусом и перемещением.Такой подход обеспечивает совместимость SortableJS с экранными читалками и стандартной навигацией через клавиатуру, что критично для корпоративных и образовательных приложений.