onStart и onEnd

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


Событие onStart

Событие onStart срабатывает в момент, когда пользователь начинает перетаскивание элемента. Оно является первым триггером в цепочке событий SortableJS и предоставляет информацию о том, какой элемент и из какого контейнера был выбран для перемещения.

Сигнатура события:

onStart: function (evt) {
    // evt.item — DOM-элемент, который начали перетаскивать
    // evt.from — родительский контейнер элемента
}

Ключевые возможности onStart:

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

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

new Sortable(document.getElementById('list'), {
    onStart: function (evt) {
        evt.item.style.backgroundColor = 'lightblue';
        console.log('Начало перетаскивания:', evt.item.textContent);
    }
});

В данном примере элемент, который пользователь начинает перемещать, изменяет цвет фона, а информация о нём выводится в консоль.


Событие onEnd

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

Сигнатура события:

onEnd: function (evt) {
    // evt.item — перемещённый элемент
    // evt.from — исходный контейнер
    // evt.to — контейнер, в котором завершилось перемещение
    // evt.oldIndex — индекс элемента до перемещения
    // evt.newIndex — новый индекс элемента
}

Ключевые возможности onEnd:

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

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

new Sortable(document.getElementById('list'), {
    onEnd: function (evt) {
        evt.item.style.backgroundColor = '';
        console.log(`Элемент перемещён с позиции ${evt.oldIndex} на позицию ${evt.newIndex}`);
    }
});

Здесь после завершения перетаскивания цвет элемента возвращается к исходному состоянию, а информация о перемещении выводится в консоль.


Совместное использование onStart и onEnd

Использование событий onStart и onEnd вместе позволяет полностью контролировать процесс перетаскивания:

  • Отслеживание изменений порядка элементов: фиксируются начальная и конечная позиции, что удобно для сохранения состояния списка.
  • Визуальные анимации: изменение внешнего вида элемента только во время перетаскивания и возврат к нормальному состоянию после.
  • Логирование действий пользователя: сбор полной истории перетаскиваний для аналитики.

Пример комплексной реализации:

new Sortable(document.getElementById('list'), {
    animation: 150,
    onStart: function (evt) {
        evt.item.classList.add('dragging');
    },
    onEnd: function (evt) {
        evt.item.classList.remove('dragging');
        console.log(`Элемент "${evt.item.textContent}" перемещён с ${evt.oldIndex} на ${evt.newIndex}`);
        updateDataModel(evt.oldIndex, evt.newIndex);
    }
});

function updateDataModel(oldIndex, newIndex) {
    const items = dataModel.splice(oldIndex, 1);
    dataModel.splice(newIndex, 0, items[0]);
}

В этом примере элемент получает CSS-класс dragging во время перетаскивания, который затем удаляется, а изменения синхронизируются с внутренним массивом данных dataModel.


Практические советы

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

События onStart и onEnd в SortableJS обеспечивают полный контроль над процессом сортировки, позволяя создавать интерактивные и отзывчивые интерфейсы с точной обработкой действий пользователя.