Drag handles

SortableJS — это мощная библиотека для реализации перетаскивания элементов в списках и сетках на веб-странице. Одной из ключевых возможностей является использование drag handles — специальных областей внутри элементов, с которых пользователь может инициировать перетаскивание. Это позволяет контролировать UX и предотвращать случайные перемещения элементов при взаимодействии с другими частями элемента.


Основные принципы drag handles

Drag handle — это дочерний элемент внутри элемента списка, который служит точкой захвата для перетаскивания. Если handle задан, перетаскивание элемента возможно только при взаимодействии с этим handle.

Использование drag handles позволяет:

  • Исключить случайное перемещение при кликах на другие элементы.
  • Разграничить зоны для взаимодействия (например, кнопки внутри элемента и область перетаскивания).
  • Создавать более сложные интерфейсы с элементами управления внутри draggable блока.

Настройка drag handle

Для задания drag handle в SortableJS используется опция handle при инициализации sortable:

const sortable = new Sortable(document.getElementById('list'), {
    handle: '.drag-handle',
    animation: 150,
});

Здесь:

  • handle: '.drag-handle' — селектор CSS, определяющий дочерний элемент, с которого разрешено перетаскивание.
  • animation: 150 — добавляет плавную анимацию при перемещении элементов.

В этом примере, только элементы с классом .drag-handle будут инициировать drag. Если кликнуть на другой элемент списка, перемещение не произойдёт.


Комбинирование с другими опциями

SortableJS позволяет сочетать drag handles с другими настройками для достижения гибкого поведения:

  1. filter — позволяет исключить определённые элементы из перетаскивания, даже если клик на них происходит внутри handle.
const sortable = new Sortable(document.getElementById('list'), {
    handle: '.drag-handle',
    filter: '.no-drag',
    animation: 200,
});
  • Элементы с классом .no-drag не будут перетаскиваться, даже если находятся внутри handle.
  1. draggable — задаёт, какие элементы могут быть перетаскиваемыми в списке. Например:
draggable: 'li.item'

В сочетании с handle это позволяет строго контролировать, какие элементы и с каких частей можно перемещать.


Динамическое добавление handle

Handle можно добавлять или изменять динамически после инициализации SortableJS. Для этого используется метод option:

sortable.option('handle', '.new-drag-handle');

После выполнения этой строки элементы с новым классом .new-drag-handle будут использоваться в качестве точек захвата для перетаскивания.


События и drag handles

Использование drag handles не влияет на стандартные события SortableJS. Основные события:

  • onStart(evt) — срабатывает при начале перетаскивания. evt.handle позволяет получить DOM-элемент handle, с которого начался drag.
  • onEnd(evt) — срабатывает после завершения перетаскивания.
  • onMove(evt) — позволяет определить, можно ли перемещать элемент на определённое место, поддерживает проверку handle.

Пример использования события onStart с handle:

const sortable = new Sortable(document.getElementById('list'), {
    handle: '.drag-handle',
    onStart: function(evt) {
        console.log('Перетаскивание начато с handle:', evt.handle);
    }
});

Особенности работы с nested lists

При вложенных списках drag handles помогают точно контролировать, с какого элемента начинается перетаскивание. Например, в деревьях с вложенными <ul> часто используют handle только на иконке или заголовке элемента, чтобы предотвращать перемещение при кликах на текст или вложенные элементы.

<ul id="tree">
    <li>
        <span class="drag-handle">≡</span> Категория 1
        <ul>
            <li><span class="drag-handle">≡</span> Подкатегория 1</li>
        </ul>
    </li>
</ul>

В этом случае, перетаскивание возможно только при захвате элемента с классом .drag-handle.


Рекомендации по использованию

  • Всегда делегировать drag handle на невидимые или небольшие интерактивные элементы, чтобы основной контент оставался кликабельным.
  • Для элементов с интерактивными кнопками внутри (например, редактирование или удаление) использование drag handle предотвращает конфликт событий.
  • Стараться задавать CSS-селектор handle уникально, чтобы избежать непреднамеренного перетаскивания других частей интерфейса.

Визуальная индикация handle

Для удобства пользователя drag handle обычно визуализируют:

  • Иконкой «≡» или «⠿».
  • Изменением курсора CSS: cursor: grab;
  • Подсветкой при наведении: :hover { background-color: #eee; }

Пример CSS:

.drag-handle {
    cursor: grab;
    padding: 4px;
    margin-right: 8px;
}
.drag-handle:active {
    cursor: grabbing;
}

Такой подход делает интерфейс более интуитивным и предотвращает случайные перемещения.


Использование drag handles в SortableJS обеспечивает точный контроль над пользовательским взаимодействием с элементами списка, улучшает UX и позволяет создавать сложные и удобные интерфейсы с множеством интерактивных элементов внутри перетаскиваемых блоков.