drag:over и drag:out

В библиотеке Shopify Draggable события drag:over и drag:out играют ключевую роль в управлении поведением элементов при перетаскивании. Они позволяют отслеживать момент, когда перетаскиваемый элемент входит в область другого элемента (контейнера или допустимой цели) и когда покидает её. Эти события дают возможность реализовать визуальные эффекты, проверку допустимости перемещений и динамическую реакцию интерфейса.


drag:over

Событие drag:over срабатывает в момент, когда перетаскиваемый элемент входит в границы другого элемента, который может выступать в роли контейнера или зоны, поддерживающей дроп.

Параметры события:

  • event.dragEvent: объект события перетаскивания (MouseEvent или TouchEvent).
  • event.source: элемент, который перетаскивается.
  • event.over: элемент, над которым находится перетаскиваемый объект.
  • event.cancelable: флаг, показывающий возможность отмены действия.

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

const container = document.querySelector('.container');
const draggable = new Draggable.Sortable(container, {
  draggable: '.item'
});

draggable.on('drag:over', (event) => {
  event.over.classList.add('highlight');
  console.log(`Элемент ${event.source.textContent} находится над ${event.over.textContent}`);
});

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

Ключевые моменты drag:over:

  • Может срабатывать многократно, если элемент движется внутри одного контейнера.
  • Используется для динамического изменения стиля или для валидации дроп-зоны.
  • Позволяет предотвратить ненужные действия с помощью event.cancelable и метода event.preventDefault().

drag:out

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

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

draggable.on('drag:out', (event) => {
  event.over.classList.remove('highlight');
  console.log(`Элемент ${event.source.textContent} покинул ${event.over.textContent}`);
});

Особенности drag:out:

  • Гарантирует снятие визуального выделения при уходе элемента.
  • Может использоваться для сброса состояния логики, связанной с дроп-зоной.
  • В отличие от drag:over, событие drag:out не передает информацию о следующем элементе над которым находится перетаскиваемый объект — только о том, откуда он вышел.

Взаимодействие drag:over и drag:out

Совместное использование этих событий позволяет реализовать плавное взаимодействие с дроп-зонами:

  1. Подсветка зоны: drag:over добавляет класс для визуального эффекта, drag:out — удаляет его.
  2. Валидация дроп-зоны: на drag:over проверяется допустимость перемещения, на drag:out можно отменить временные изменения.
  3. Анимации и переходы: при входе элемента в зону запускаются анимации, а при выходе — обратные эффекты.

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

draggable.on('drag:over', (event) => {
  if (event.over.classList.contains('drop-zone')) {
    event.over.classList.add('active');
  }
});

draggable.on('drag:out', (event) => {
  event.over.classList.remove('active');
});

Практические рекомендации

  • Минимизировать работу с DOM в событиях. Частые манипуляции могут замедлить перетаскивание.
  • Использовать делегирование классов для подсветки зон вместо изменения стиля напрямую.
  • Проверять структуру контейнеров: события срабатывают только для элементов, зарегистрированных в Draggable.
  • Комбинировать с drag:over:container и drag:out:container для обработки входа и выхода не отдельных элементов, а целых контейнеров.

Отличие от drag:enter и drag:leave

Хотя по смыслу похожи, drag:over/drag:out в Shopify Draggable отличаются от стандартных dragenter/dragleave HTML5:

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

Эффективное использование drag:over и drag:out обеспечивает точный контроль над поведением перетаскиваемых элементов, позволяет создавать интерактивные дроп-зоны, анимации и динамическое управление состояниями интерфейса, что делает пользовательский опыт более отзывчивым и интуитивным.