Фокус и табуляция

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 — завершение сортировки внутри контейнера.

События можно использовать для синхронизации состояния интерфейса с данными приложения, например, обновления хранилища или уведомления пользователя о изменении порядка элементов.

Управление доступностью

Для поддержания доступности:

  1. Использовать tabindex для всех интерактивных элементов.
  2. Обеспечивать видимые индикаторы фокуса через CSS.
  3. Сохранять порядок элементов при изменении DOM с помощью store.
  4. Обрабатывать клавиши стрелок и Enter для управления фокусом и перемещением.

Такой подход обеспечивает совместимость SortableJS с экранными читалками и стандартной навигацией через клавиатуру, что критично для корпоративных и образовательных приложений.