Списки задач

SortableJS — это легковесная и гибкая библиотека для организации сортируемых списков на стороне клиента с поддержкой drag-and-drop. Для её использования достаточно подключить скрипт через CDN или npm:

<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>

или через npm:

npm install sortablejs

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

<ul id="tasks">
    <li>Задача 1</li>
    <li>Задача 2</li>
    <li>Задача 3</li>
</ul>

<script>
    const tasksList = document.getElementById('tasks');
    new Sortable(tasksList, {
        animation: 150
    });
</script>

Ключевой параметр animation задаёт плавность перетаскивания элементов списка.

Настройка параметров сортировки

SortableJS предоставляет широкий набор опций для тонкой настройки поведения:

  • handle — задаёт конкретный элемент, за который можно перетаскивать элемент списка:
new Sortable(tasksList, {
    handle: '.drag-handle'
});
  • draggable — позволяет определить, какие элементы могут быть перетаскиваемыми:
new Sortable(tasksList, {
    draggable: 'li:not(.locked)'
});
  • ghostClass — CSS-класс, применяемый к элементу во время перетаскивания:
new Sortable(tasksList, {
    ghostClass: 'dragging'
});
  • filter и preventOnFilter — исключают элементы из сортировки, например, кнопки удаления:
new Sortable(tasksList, {
    filter: '.delete-btn',
    preventOnFilter: false
});

События и обработка действий

SortableJS генерирует множество событий, позволяющих управлять действиями пользователя:

  • onStart — при начале перетаскивания
  • onEnd — по завершении перемещения элемента
  • onAdd — при добавлении элемента из другого списка
  • onUpdate — после изменения порядка в списке
  • onRemove — при удалении элемента из списка
  • onSort — при любом действии сортировки

Пример использования:

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

Множественные списки и обмен элементами

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

<ul id="todo">
    <li>Задача A</li>
    <li>Задача B</li>
</ul>
<ul id="done">
    <li>Задача C</li>
</ul>

<script>
new Sortable(document.getElementById('todo'), {
    group: 'tasks',
    animation: 150
});

new Sortable(document.getElementById('done'), {
    group: 'tasks',
    animation: 150
});
</script>

Опция group может быть объектом с настройками name, pull и put, что позволяет гибко управлять перемещением элементов между списками:

group: {
    name: 'tasks',
    pull: 'clone', // копировать элементы при перетаскивании
    put: false     // запрет на добавление элементов в список
}

Сортировка с сохранением состояния

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

function saveOrder(listId) {
    const order = Array.from(document.getElementById(listId).children).map(li => li.textContent);
    localStorage.setItem(listId, JSON.stringify(order));
}

function loadOrder(listId) {
    const order = JSON.parse(localStorage.getItem(listId));
    if (!order) return;
    const list = document.getElementById(listId);
    list.innerHTML = '';
    order.forEach(text => {
        const li = document.createElement('li');
        li.textContent = text;
        list.appendChild(li);
    });
}

loadOrder('tasks');
new Sortable(document.getElementById('tasks'), {
    animation: 150,
    onEnd: () => saveOrder('tasks')
});

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

SortableJS легко интегрируется с CSS для улучшения UX:

  • Добавление визуального эффекта при перетаскивании:
.dragging {
    opacity: 0.5;
    border: 2px dashed #aaa;
}
  • Использование кастомного «хэндла» для перетаскивания:
<li><span class="drag-handle">≡</span> Задача 1</li>
  • Настройка чувствительности к перетаскиванию через touchStartThreshold для мобильных устройств:
new Sortable(tasksList, {
    animation: 150,
    touchStartThreshold: 5
});

Расширенные возможности

SortableJS позволяет:

  • Реализовать drag-and-drop с элементами, которые динамически добавляются в список.
  • Использовать swap и sort режимы для нестандартного поведения сортировки.
  • Интегрироваться с фреймворками, такими как Vue, React и Angular, через официальные обёртки.
  • Настраивать ограничение по направлению перетаскивания с помощью direction: 'vertical' или 'horizontal'.

Практический пример: список задач с приоритетами

<ul id="high-priority">
    <li>Срочная задача 1</li>
</ul>
<ul id="low-priority">
    <li>Обычная задача 1</li>
</ul>

<script>
const high = document.getElementById('high-priority');
const low = document.getElementById('low-priority');

Sortable.create(high, {
    group: 'priority',
    animation: 150
});

Sortable.create(low, {
    group: 'priority',
    animation: 150
});
</script>

Этот подход позволяет организовать задачи по категориям, легко перемещать их между приоритетами и сохранять порядок с помощью событий onEnd.

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