Блокировка определенных элементов

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

Использование опции moves

Главным инструментом для ограничения перетаскивания является функция moves. Она вызывается при каждой попытке начать перенос элемента и принимает три параметра:

function moves(el, source, handle, sibling) {
    // el — DOM-элемент, который пытаются перетащить
    // source — контейнер, из которого элемент берут
    // handle — элемент, по которому пользователь нажал мышью
    // sibling — элемент, перед которым потенциально вставят el
}

Функция должна возвращать true, если элемент разрешено перетаскивать, и false, если нет. Например:

const drake = dragula([document.querySelector('#list')], {
    moves: function(el, source, handle, sibling) {
        return !el.classList.contains('locked');
    }
});

В этом примере все элементы с классом locked не подлежат перемещению. Остальные можно перетаскивать обычным способом.

Ограничение по контейнеру

Иногда необходимо запретить перемещение элементов в определённые контейнеры или ограничить перетаскивание только между определёнными списками. Для этого используется опция accepts:

const drake = dragula([container1, container2], {
    accepts: function(el, target, source, sibling) {
        // target — контейнер, куда пытаются переместить элемент
        return !el.classList.contains('locked') && target.id !== 'forbidden';
    }
});

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

Блокировка отдельных областей внутри элемента

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

const drake = dragula([document.querySelector('#list')], {
    moves: function(el, source, handle) {
        return handle.classList.contains('drag-handle');
    }
});

Теперь перетаскивание сработает только при захвате элемента с классом drag-handle, а клики по остальной части элемента не будут инициировать drag.

Временная блокировка элементов

Для динамических интерфейсов может потребоваться временно блокировать элементы, например, в зависимости от состояния приложения. Это реализуется изменением классов или атрибутов DOM и проверкой их в функции moves:

function toggleLock(el, lock) {
    if (lock) {
        el.classList.add('locked');
    } else {
        el.classList.remove('locked');
    }
}

const drake = dragula([document.querySelector('#list')], {
    moves: function(el) {
        return !el.classList.contains('locked');
    }
});

Эта схема позволяет включать или отключать возможность перемещения элементов без необходимости пересоздавать Dragula-инстанс.

Сочетание блокировки и визуальной обратной связи

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

.locked {
    opacity: 0.5;
    cursor: not-allowed;
}

JavaScript и CSS вместе обеспечивают наглядное отображение состояния элемента и предотвращают попытки перетаскивания.

Полезные приёмы

  • Использование dataset для хранения состояния блокировки, вместо классов:
el.dataset.locked === "true"
  • Комбинирование moves и accepts для сложных сценариев: запрет на drag и на drop одновременно.
  • Динамическое добавление и удаление контейнеров из Dragula, чтобы контролировать доступные зоны перемещения.

Итоговая структура

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

  1. moves — управление возможностью начать перетаскивание.
  2. accepts — определение допустимых контейнеров для вставки.
  3. Визуальная и программная маркировка заблокированных элементов — классы, атрибуты или dataset.

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