Порядок срабатывания событий

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

Инициализация Dragula

Для начала работы создается экземпляр Dragula, которому передается массив контейнеров:

const drake = dragula([container1, container2]);

После инициализации все элементы внутри указанных контейнеров становятся перетаскиваемыми. По умолчанию Dragula использует простую логику: любой элемент внутри контейнера можно перетащить, а любой контейнер может принять любой элемент.

События Dragula

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

drag

Срабатывает при начале перетаскивания элемента. На этом этапе создается внутреннее представление перетаскиваемого элемента (mirror), которое следует за курсором. Основные параметры события:

  • el — перетаскиваемый элемент.
  • source — контейнер, из которого был взят элемент.

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

drake.on('drag', (el, source) => {
    el.style.opacity = '0.5';
});

dragend

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

drake.on('dragend', (el) => {
    el.style.opacity = '';
});

over и out

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

  • over — элемент находится над контейнером и потенциально может быть туда вставлен.
  • out — элемент покидает контейнер без вставки.

Параметры:

  • el — перемещаемый элемент.
  • container — контейнер, над которым или из которого происходит событие.
  • source — исходный контейнер (для over и out совпадает с container).
drake.on('over', (el, container) => {
    container.classList.add('highlight');
});

drake.on('out', (el, container) => {
    container.classList.remove('highlight');
});

drop

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

drake.on('drop', (el, target, source, sibling) => {
    console.log(`Элемент перемещен из ${source.id} в ${target.id}`);
});

Параметры:

  • el — перемещаемый элемент.
  • target — контейнер, куда элемент вставлен.
  • source — исходный контейнер.
  • sibling — элемент, перед которым был вставлен el. Может быть null при вставке в конец.

cancel

Срабатывает, если перетаскивание было отменено, например, если элемент отпущен за пределами допустимого контейнера. Позволяет откатить визуальные изменения.

drake.on('cancel', (el, container, source) => {
    console.log('Перетаскивание отменено');
});

remove

Происходит, когда элемент удаляется из контейнера, если Dragula настроен на удаление при выходе за пределы контейнера (removeOnSpill: true). Параметры идентичны drop.

Порядок срабатывания событий

Важно понимать последовательность, в которой Dragula вызывает события:

  1. drag — пользователь начал перетаскивать элемент. Создано зеркало (mirror), исходный элемент полупрозрачный.
  2. over — элемент наведен на контейнер.
  3. out — элемент покидает контейнер, не вставляясь.
  4. Повторяющееся чередование over / out при перемещении между контейнерами.
  5. drop — элемент вставлен в целевой контейнер. Если вставки не произошло, событие не вызывается.
  6. dragend — перетаскивание завершено, зеркало удалено, элемент вернул исходное состояние.
  7. cancel — если вставка невозможна и элемент возвращен в исходный контейнер.
  8. remove — если элемент удаляется из контейнера при настройке removeOnSpill.

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

Настройки и модификация поведения событий

Dragula позволяет изменять порядок или условия срабатывания событий через конфигурацию:

  • moves(el, source, handle, sibling) — управляет, можно ли перетаскивать конкретный элемент.
  • accepts(el, target, source, sibling) — проверяет, может ли элемент быть вставлен в конкретный контейнер.
  • invalid(el, handle) — запрещает перетаскивание для определенных элементов.
  • copy(el, source) — создает копию элемента вместо перемещения.
  • removeOnSpill — удаляет элемент, если он отпущен за пределами контейнера.

Применение этих опций позволяет точно управлять логикой drag-and-drop без вмешательства в внутренние события Dragula.

Примеры комбинирования событий

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

drake.on('drag', (el) => el.classList.add('dragging'));
drake.on('over', (el, container) => container.classList.add('hovered'));
drake.on('out', (el, container) => container.classList.remove('hovered'));
drake.on('drop', (el, target) => target.classList.remove('hovered'));
drake.on('dragend', (el) => el.classList.remove('dragging'));

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


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