accepts - определение допустимости размещения

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

accepts: function (el, target, source, sibling) { ... }

Аргументы функции:

  • el — DOM-элемент, который перетаскивается.
  • target — контейнер, в который пытаются поместить элемент.
  • source — контейнер, из которого элемент был взят.
  • sibling — элемент, перед которым вставляется el в target; если вставка происходит в конец контейнера, значение будет null.

Возвращаемое значение должно быть булевым: true означает разрешение перемещения, false — запрет.


Простые сценарии использования

  1. Ограничение по типу контейнера Разрешить перемещение элемента только в определённый контейнер:
dragula([container1, container2], {
    accepts: function (el, target) {
        return target.id === 'container2';
    }
});

В этом примере элементы из любого контейнера могут быть перемещены только в container2.

  1. Фильтрация по классу элемента Можно разрешить перенос только элементов с конкретным классом:
dragula([container1, container2], {
    accepts: function (el) {
        return el.classList.contains('draggable');
    }
});

Все элементы без класса draggable останутся неподвижными.


Более сложные условия

  1. Запрет на перемещение между контейнерами Иногда необходимо запретить перемещение между определёнными контейнерами:
dragula([containerA, containerB], {
    accepts: function (el, target, source) {
        if (source.id === 'containerA' && target.id === 'containerB') {
            return false;
        }
        return true;
    }
});
  1. Контроль позиции вставки sibling позволяет управлять местом вставки элемента:
dragula([container], {
    accepts: function (el, target, source, sibling) {
        if (sibling && sibling.classList.contains('fixed-position')) {
            return false;
        }
        return true;
    }
});

В этом случае элементы не могут быть вставлены перед элементами с классом fixed-position.


Практическое использование с динамическими условиями

  1. Условия на основе атрибутов данных
dragula([container1, container2], {
    accepts: function (el, target) {
        const allowedType = target.getAttribute('data-accept');
        const elType = el.getAttribute('data-type');
        return allowedType === elType;
    }
});

Каждый контейнер может принимать только элементы с совпадающим типом, определённым через data- атрибуты.

  1. Ограничение количества элементов в контейнере
dragula([container], {
    accepts: function (el, target) {
        const maxItems = parseInt(target.getAttribute('data-max'), 10);
        return target.children.length < maxItems;
    }
});

Такой подход предотвращает переполнение контейнера и позволяет динамически контролировать вместимость.


Совмещение условий

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

dragula([container1, container2], {
    accepts: function (el, target, source, sibling) {
        const typeMatches = el.getAttribute('data-type') === target.getAttribute('data-accept');
        const underLimit = target.children.length < 5;
        const notBeforeFixed = !(sibling && sibling.classList.contains('fixed-position'));
        return typeMatches && underLimit && notBeforeFixed;
    }
});

Здесь одновременно проверяются три условия: тип элемента, количество детей в контейнере и позиция вставки. Только если все три условия выполняются, перетаскивание разрешено.


Рекомендации по производительности

  • Минимизировать сложные вычисления внутри функции accepts, особенно при больших списках элементов.
  • Использовать кэширование атрибутов или классов, чтобы не обращаться к DOM несколько раз.
  • Комбинировать accepts с moves, если нужно сначала проверять возможность начала перетаскивания, а потом место вставки.

Взаимодействие с другими опциями Dragula

  • moves — контролирует, можно ли начать перетаскивание; accepts — куда элемент может быть перемещён.
  • invalid — исключает элементы из перетаскивания совсем, а accepts позволяет более гибко фильтровать их размещение.
  • copy — при копировании элементов функция accepts применяет те же правила к новым элементам.

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