Проверка допустимости сброса

Interact.js предоставляет мощные возможности для перетаскивания и взаимодействия с элементами DOM. Одним из ключевых аспектов сложных интерфейсов является контроль допустимости сброса (drop), чтобы элементы можно было размещать только в определённых зонах. Для этого используется система dropzone и события, связанные с проверкой попадания перетаскиваемого объекта в целевую область.


Определение зоны сброса

Чтобы элемент мог принимать другие объекты, необходимо определить его как dropzone:

interact('.dropzone').dropzone({
  accept: '.draggable',
  overlap: 0.5,
  ondropactivate: function (event) {
    event.target.classList.add('drop-active');
  },
  ondragenter: function (event) {
    event.target.classList.add('drop-target');
    event.relatedTarget.classList.add('can-drop');
  },
  ondragleave: function (event) {
    event.target.classList.remove('drop-target');
    event.relatedTarget.classList.remove('can-drop');
  },
  ondrop: function (event) {
    console.log('Элемент успешно сброшен в dropzone');
  },
  ondropdeactivate: function (event) {
    event.target.classList.remove('drop-active');
    event.target.classList.remove('drop-target');
  }
});

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

  • accept — CSS-селектор для элементов, которые разрешено сбрасывать.
  • overlap — минимальная доля пересечения перетаскиваемого элемента с зоной для того, чтобы сброс считался допустимым. Значение 0.5 означает, что половина элемента должна находиться внутри dropzone.
  • События ondragenter, ondragleave и ondrop позволяют визуально и программно реагировать на попадание элемента в dropzone.

Проверка допустимости сброса через функцию

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

interact('.dropzone').dropzone({
  checker: function (dragEvent, event, dropped, dropzone, dropElement, draggable, draggableElement) {
    // Допустим сброс только если элемент не имеет класса 'forbidden'
    if (draggableElement.classList.contains('forbidden')) {
      return null;
    }
    // Допустим, что элемент можно сбросить только в левую половину зоны
    const dropRect = dropzone.getBoundingClientRect();
    const dragRect = draggableElement.getBoundingClientRect();
    if (dragRect.left + dragRect.width / 2 > dropRect.left + dropRect.width / 2) {
      return null;
    }
    return { dropzone, draggable: draggableElement };
  }
});

Особенности checker:

  • Возвращает объект с dropzone и draggable для допустимого сброса.
  • Возврат null или false запрещает сброс.
  • Позволяет учитывать любые условия: классы, атрибуты, координаты, пользовательские свойства.

Использование overlap для точной настройки

Параметр overlap может быть задан числом, строкой или функцией:

  • Число (0–1) — процент пересечения.

  • Строка:

    • 'pointer' — учитывает позицию курсора при определении допустимости.
    • 'center' — учитывает центр перетаскиваемого элемента.
  • Функция — вычисляет пересечение динамически:

interact('.dropzone').dropzone({
  overlap: function (dragRect, dropRect) {
    const intersectionWidth = Math.max(0, Math.min(dragRect.right, dropRect.right) - Math.max(dragRect.left, dropRect.left));
    const intersectionHeight = Math.max(0, Math.min(dragRect.bottom, dropRect.bottom) - Math.max(dragRect.top, dropRect.top));
    const intersectionArea = intersectionWidth * intersectionHeight;
    const dragArea = dragRect.width * dragRect.height;
    return intersectionArea / dragArea; // возвращаем процент пересечения
  }
});

Использование функции позволяет реализовать индивидуальные правила пересечения для каждой dropzone, например, требовать более 80% попадания в одну зону и 50% в другую.


Динамическое включение и отключение dropzone

Interact.js позволяет включать и отключать зоны сброса в реальном времени:

const dz = interact('.dropzone');

// Отключение dropzone
dz.dropzone({ enabled: false });

// Включение dropzone
dz.dropzone({ enabled: true });

Это особенно полезно, если нужно запретить сброс в определённые моменты, например, пока выполняется анимация или идет проверка данных.


События для мониторинга допустимости

  • ondragenter — срабатывает, когда перетаскиваемый объект вошёл в область, допустимую для сброса.
  • ondragleave — когда объект покидает допустимую область.
  • ondropactivate и ondropdeactivate — включают и выключают визуальные состояния для всех dropzone при начале и завершении перетаскивания.

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


Пример сложной проверки

Можно объединять проверку через checker и события для реализации комплексных правил:

interact('.dropzone').dropzone({
  accept: '.draggable',
  checker: function (dragEvent, event, dropped, dropzone, dropElement, draggable, draggableElement) {
    if (!draggableElement.dataset.allowed) return null;
    return { dropzone, draggable: draggableElement };
  },
  ondragenter: function (event) {
    event.target.style.background = 'lightgreen';
  },
  ondragleave: function (event) {
    event.target.style.background = '';
  },
  ondrop: function (event) {
    event.target.appendChild(event.relatedTarget);
  }
});

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


Interact.js предоставляет гибкий механизм для проверки допустимости сброса, позволяя сочетать простые правила через селекторы и overlap и сложные логики через функции checker и события. Это делает библиотеку удобной для создания интерактивных интерфейсов с точным контролем поведения перетаскиваемых элементов.