Расширение прототипа Drake

Dragula — это легковесная JavaScript-библиотека, предназначенная для реализации функционала перетаскивания элементов между контейнерами без необходимости глубокого вмешательства в DOM или использование сложных API. Центральным объектом в Dragula является drake — экземпляр, управляющий логикой перетаскивания и событиями.

Создание экземпляра drake происходит через функцию dragula(containers, options), где:

  • containers — массив DOM-элементов, между которыми разрешено перемещение.
  • options — объект с настройками поведения перетаскивания.

Примеры ключевых опций:

  • moves(el, source, handle, sibling) — функция, определяющая, разрешено ли перетаскивание конкретного элемента.
  • accepts(el, target, source, sibling) — функция, определяющая, можно ли вставить элемент в конкретный контейнер.
  • copy — логическое значение или функция, указывающая, копировать элемент при перемещении или нет.
  • revertOnSpill — при true элемент возвращается на исходное место при “пролитии” за пределы контейнера.
  • removeOnSpill — при true элемент удаляется, если его бросили вне разрешённых контейнеров.

События и их обработка

Объект drake поддерживает широкий спектр событий, позволяя контролировать все стадии перетаскивания:

  • drag — начинается перетаскивание элемента.
  • drop — элемент был успешно сброшен в новый контейнер.
  • over — элемент перемещается над контейнером.
  • out — элемент покидает контейнер во время перетаскивания.
  • cancel — отмена перетаскивания.
  • cloned — элемент был клонирован (если включена опция copy).

Пример добавления обработчика события:

drake.on('drop', function(el, target, source, sibling) {
    console.log('Элемент', el, 'перемещён из', source, 'в', target);
});

Расширение прототипа Drake

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

dragula.prototype.customMethod = function() {
    console.log('Вызов пользовательского метода Drake');
};

После добавления метода он становится доступен любому экземпляру drake:

const drake = dragula([...containers]);
drake.customMethod(); // Вызов нового метода

Добавление пользовательских хуков

Для более гибкого контроля можно создавать методы-хуки, вызываемые в определённые моменты перетаскивания:

dragula.prototype.beforeDrop = function(callback) {
    this.on('drop', function(el, target, source, sibling) {
        callback(el, target, source, sibling);
    });
};

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

drake.beforeDrop(function(el, target, source) {
    if (!target.classList.contains('allowed')) {
        console.log('Элемент не может быть перемещён в этот контейнер');
        drake.cancel(true); // Отмена перетаскивания
    }
});

Переопределение стандартных методов

Можно переопределять методы drake для изменения базового поведения. Например, изменение алгоритма копирования элементов:

const originalCopy = dragula.prototype._copy;

dragula.prototype._copy = function(el) {
    const cloned = originalCopy.call(this, el);
    cloned.style.backgroundColor = '#f0f0f0';
    return cloned;
};

Это позволяет создавать собственные визуальные эффекты и функциональные модификации без потери совместимости с остальными функциями библиотеки.

Взаимодействие с внешними библиотеками

Расширенный drake легко интегрируется с фреймворками и библиотеками, например с React, Vue или Angular, через методы обратного вызова и хуки событий. Основное преимущество — можно добавлять реактивное обновление состояния или синхронизацию с сервером без переписывания логики перетаскивания.

Пример синхронизации с React:

drake.on('drop', (el, target, source) => {
    const itemId = el.dataset.id;
    const newContainerId = target.dataset.container;
    updateState(itemId, newContainerId); // функция обновления состояния React
});

Советы по расширению

  • Все новые методы должны быть добавлены к dragula.prototype, чтобы они наследовались всеми экземплярами.
  • Для совместимости с будущими версиями библиотеки избегать изменения существующих приватных методов напрямую — лучше создавать обёртки.
  • Использование событий Dragula вместе с пользовательскими методами позволяет полностью контролировать жизненный цикл элемента.
  • Обеспечивать откат к стандартному поведению через хранение оригинальных методов перед переопределением.

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