onMove и onClone

SortableJS — это мощная библиотека для реализации интерактивного перетаскивания элементов на веб-странице. Она предоставляет гибкую систему событий и опций, среди которых onMove и onClone играют ключевую роль при управлении поведением перетаскиваемых элементов и их копий.


Событие onMove

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

Подпись функции:

onMove: function (evt, originalEvent) {
    // возвращает true или false
}

Параметры:

  • evt — объект события Sortable, содержит:

    • evt.dragged — DOM-элемент, который перетаскивается.
    • evt.related — элемент, над которым в данный момент находится курсор.
    • evt.willInsertAfter — булево значение, показывает, будет ли элемент вставлен после related.
    • evt.from — исходный контейнер.
    • evt.to — целевой контейнер.
  • originalEvent — нативное событие браузера (MouseEvent или TouchEvent).

Пример использования для блокировки определённых элементов:

new Sortable(list, {
    onMove: function (evt) {
        if (evt.related && evt.related.classList.contains('no-drop')) {
            return false; // запрещает вставку на элемент с классом no-drop
        }
        return true; // разрешает перемещение
    }
});

Особенности и рекомендации:

  • onMove должен возвращать булево значение. true разрешает вставку, false — блокирует.
  • Используется для динамических правил сортировки, например, ограничение по типу элементов.
  • Можно использовать для визуальных эффектов, например, подсветки допустимых зон перетаскивания через добавление CSS-классов к evt.related.

Событие onClone

Событие onClone срабатывает при создании копии перетаскиваемого элемента. Это особенно важно при использовании опции pull: 'clone' в группах сортировки, когда исходный элемент остаётся на месте, а создаётся его копия для перемещения.

Подпись функции:

onClone: function (evt) {
    // evt.clone содержит клон элемента
}

Параметры:

  • evt.clone — новый DOM-элемент, созданный как копия перетаскиваемого.
  • evt.dragged — исходный элемент.
  • evt.from — контейнер исходного элемента.

Пример изменения внешнего вида клона:

new Sortable(list, {
    group: { name: 'shared', pull: 'clone', put: false },
    onClone: function (evt) {
        evt.clone.style.backgroundColor = 'lightblue';
        evt.clone.textContent += ' (клон)';
    }
});

Особенности и рекомендации:

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

Совместное использование onMove и onClone

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

  1. onMove контролирует разрешение вставки, предотвращая попадание элементов в недопустимые зоны.
  2. onClone позволяет модифицировать копию, если элемент перемещается в другую группу с особым оформлением или логикой.

Пример комплексной конфигурации:

new Sortable(listA, {
    group: { name: 'shared', pull: 'clone', put: true },
    onMove: function (evt) {
        // запрещаем перенос элементов с классом 'locked'
        return !evt.dragged.classList.contains('locked');
    },
    onClone: function (evt) {
        // добавляем визуальный индикатор клона
        evt.clone.classList.add('clone-highlight');
    }
});

new Sortable(listB, {
    group: 'shared'
});

В этом примере:

  • Перетаскивание заблокировано для элементов с классом locked.
  • Все клонированные элементы получают дополнительный класс для стилизации.
  • Элементы можно перемещать между listA и listB, при этом исходный элемент остаётся на месте, а клон появляется в целевом контейнере.

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

  • Использование onMove экономит ресурсы, так как запрещает ненужные DOM-операции заранее.
  • onClone полезен для динамического создания контента, например, при визуальном редакторе или списках товаров.
  • Для сложных интерфейсов рекомендуется комбинировать onMove с проверкой evt.to и evt.from, чтобы управлять доступными зонами перемещения в разных контейнерах.
  • Для прозрачности кода стоит делать возвращаемые значения явными (true/false) и избегать побочных эффектов в onMove.

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