Клавиатурная навигация

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

Включение поддержки клавиатуры

Для активации клавиатурной навигации необходимо использовать опцию forceFallback и подключить модуль SortableKeyboardPlugin.

import Sortable from 'sortablejs';
import { Keyboard } from '@shopify/draggable'; // при использовании расширений

const list = document.getElementById('sortable-list');

Sortable.create(list, {
    animation: 150,
    fallbackOnBody: true,
    swapThreshold: 0.65,
    forceFallback: true,
    keyboard: true
});

Опция keyboard: true позволяет управлять элементами списка с помощью стандартных клавиш: стрелок, Enter и пробела.

Основные клавиши управления

  • Стрелки вверх/вниз – перемещение фокуса между элементами списка.
  • Пробел – активация режима перетаскивания для текущего элемента.
  • Enter – фиксация позиции элемента после завершения перемещения.
  • Escape – отмена перемещения, возврат элемента в исходное положение.

Работа с фокусом

Для корректной работы клавиатурной навигации каждый элемент списка должен быть фокусируемым. Обычно это достигается добавлением атрибута tabindex="0":

<ul id="sortable-list">
    <li tabindex="0">Элемент 1</li>
    <li tabindex="0">Элемент 2</li>
    <li tabindex="0">Элемент 3</li>
</ul>

При этом важно, чтобы стиль при фокусе был визуально заметен, например:

li:focus {
    outline: 2px solid #007BFF;
    background-color: #E9F5FF;
}

События клавиатурного взаимодействия

SortableJS генерирует стандартные события для всех изменений, включая те, которые инициированы клавиатурой:

  • start – начало перемещения элемента.
  • move – элемент перемещается, можно отменить или изменить позицию.
  • end – завершение перемещения, включает как фиксацию, так и отмену.

Пример подписки на события:

Sortable.create(list, {
    animation: 150,
    keyboard: true,
    onEnd: function (evt) {
        console.log(`Элемент ${evt.item.textContent} перемещен с позиции ${evt.oldIndex} на ${evt.newIndex}`);
    }
});

Настройка пользовательских сочетаний клавиш

В некоторых случаях требуется изменить стандартное поведение клавиш. Для этого можно использовать обработчик события keydown на контейнере списка и самостоятельно вызывать методы SortableJS:

list.addEventListener('keydown', (event) => {
    const item = document.activeElement;
    const index = Array.from(list.children).indexOf(item);

    if (event.key === 'ArrowUp' && index > 0) {
        list.insertBefore(item, list.children[index - 1]);
        item.focus();
        event.preventDefault();
    }

    if (event.key === 'ArrowDown' && index < list.children.length - 1) {
        list.insertBefore(list.children[index + 1], item);
        item.focus();
        event.preventDefault();
    }
});

Такой подход позволяет создавать полностью кастомизированное управление списком с клавиатуры.

Доступность и ARIA

Для повышения доступности рекомендуется использовать атрибуты ARIA:

  • aria-grabbed="true|false" – указывает, захвачен ли элемент.
  • aria-dropeffect="move" – описывает действие, которое выполняется при перемещении.

Пример:

<li tabindex="0" aria-grabbed="false" aria-dropeffect="move">Элемент 1</li>

Во время перемещения значения атрибутов необходимо обновлять:

list.addEventListener('keydown', (event) => {
    const item = document.activeElement;
    if (event.key === ' ') {
        const grabbed = item.getAttribute('aria-grabbed') === 'true';
        item.setAttribute('aria-grabbed', grabbed ? 'false' : 'true');
        event.preventDefault();
    }
});

Рекомендации по UX

  • При использовании клавиатурного перемещения важно визуально выделять выбранный элемент.
  • Для длинных списков полезно поддерживать автоматическую прокрутку контейнера при перемещении за пределы видимой области.
  • Комбинация focus + aria-grabbed позволяет пользователю точно понимать текущий статус элемента и избегать ошибок при перемещении.

Клавиатурная навигация в SortableJS позволяет создавать списки с полной функциональностью перетаскивания, совместимые с современными требованиями доступности и удобства взаимодействия.