Svelte

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

Подключение библиотеки

Для использования SortableJS в проекте на Svelte можно установить её через npm:

npm install sortablejs

После установки библиотеку можно импортировать в компонент Svelte:

import Sortable from 'sortablejs';

Инициализация сортируемого списка

Создание сортируемого контейнера выполняется через конструктор Sortable, которому передается DOM-элемент и объект настроек:

let listElement;

onMount(() => {
    Sortable.create(listElement, {
        animation: 150,
        handle: '.handle',
        ghostClass: 'ghost'
    });
});

Ключевые параметры:

  • animation — скорость анимации при перемещении элемента в миллисекундах.
  • handle — селектор элемента, за который можно захватывать и перемещать элемент.
  • ghostClass — CSS-класс для визуального отображения перемещаемого элемента.

Связь с данными

Чтобы сортировка влияла на массив данных, необходимо отслеживать события onEnd, которое срабатывает после завершения перетаскивания:

let items = ['Элемент 1', 'Элемент 2', 'Элемент 3'];

onMount(() => {
    Sortable.create(listElement, {
        animation: 150,
        onEnd: (evt) => {
            const [movedItem] = items.splice(evt.oldIndex, 1);
            items.splice(evt.newIndex, 0, movedItem);
        }
    });
});

Объяснение: evt.oldIndex и evt.newIndex указывают старую и новую позиции элемента. С помощью splice элемент извлекается из массива и вставляется на новую позицию, что обеспечивает синхронизацию DOM с данными.

Использование нескольких списков

SortableJS поддерживает перетаскивание элементов между несколькими контейнерами. Для этого используется параметр group:

let listA = ['A1', 'A2', 'A3'];
let listB = ['B1', 'B2', 'B3'];

onMount(() => {
    Sortable.create(listAElement, { group: 'shared', animation: 150 });
    Sortable.create(listBElement, { group: 'shared', animation: 150 });
});

Элементы теперь можно перемещать между listA и listB. Чтобы обновлять данные, добавляется обработчик onAdd:

onAdd: (evt) => {
    const source = evt.from === listAElement ? listA : listB;
    const target = evt.to === listAElement ? listA : listB;
    const [movedItem] = source.splice(evt.oldIndex, 1);
    target.splice(evt.newIndex, 0, movedItem);
}

Настройка внешнего вида и взаимодействия

Ghost-класс и placeholder:

  • ghostClass отображает перемещаемый элемент полупрозрачным.
  • chosenClass — класс для выбранного элемента.
  • dragClass — класс, который добавляется на элемент в момент перетаскивания.

События для контроля поведения:

  • onStart — запуск перетаскивания.
  • onMove — позволяет отменять перемещение в реальном времени.
  • onUpdate — срабатывает после изменения порядка внутри контейнера.

Пример с отменой перемещения:

onMove: (evt, originalEvent) => {
    if (evt.related.classList.contains('locked')) {
        return false;
    }
}

Интеграция с Svelte: bind:this

Использование bind:this позволяет напрямую ссылаться на DOM-элемент внутри компонента Svelte:

    {#each items as item}
  • {item}
  • {/each}

bind:this={listElement} предоставляет SortableJS доступ к DOM-узлу, что упрощает инициализацию и управление событиями.

Дополнительные возможности

  • Сортировка сеток (grid) — элементы можно перемещать не только по вертикали, но и по горизонтали.
  • Фильтры и ограничения — возможность запрещать перетаскивание отдельных элементов через параметр filter.
  • Мобильная поддержка — библиотека полностью совместима с сенсорными экранами.
  • Поддержка drag-and-drop библиотек HTML5 — SortableJS использует нативное API, что повышает производительность.

Оптимизация производительности

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

  • Использовать animation: 0 при массовом обновлении элементов.
  • Минимизировать количество слушателей событий на каждом элементе.
  • Синхронизировать данные с DOM после завершения сортировки, а не в реальном времени, чтобы избежать лишних перерисовок.

Стилизация элементов

SortableJS не навязывает конкретный стиль, но часто используются классы ghost, chosen и drag для управления визуальным состоянием. Пример CSS:

.ghost {
    opacity: 0.4;
}

.chosen {
    background-color: #f0f0f0;
}

.drag {
    cursor: grabbing;
}

Эти классы помогают создать естественное ощущение перемещения элементов в интерфейсе.