Возможно, немного поздно, но я думаю, что это лучшее решение ... Будет публиковаться для документации / поиска, если другие люди сочтут это полезным
Примечание: вам также нужен элемент Position jQuery UI, загруженный в вашу сборку UI, чтобы это решение работало.
В моем примере я создаю набор перетаскиваемых «купонов», которые можно размещать в разных позициях. Только один купон может находиться в любом месте для броска в данный момент времени.
Чтобы управлять назначением купона для областей сбрасывания, я создал несколько вспомогательных объектов, которые я буду использовать для расширения объекта параметров перетаскиваемых и сбрасываемых прототипов:
var dropObj = { hasCoupon: false, couponId: null }
var couponObj = { dropId: null }
Затем (при готовности DOM) расширить:
$.extend( $.ui.droppable.prototype.options, dropObj );
$.extend( $.ui.draggable.prototype.options, couponObj );
Наконец, настройте свои draggables и droppables ... Когда вы настраиваете droppable, используйте jquery UI позиционный помощник, чтобы помочь поменять местами draggables ...
$('.selector').droppable({
drop: function( event, ui ) {
var current, swapId;
if ( $(this).droppable('option', 'hasCoupon') === false ) {
// ...
} else {
current = $(this).droppable('option', 'couponId');
swapId = ui.draggable.draggable('option', 'dropId');
if ( swapId !== null ){
current.position({
my: "center", at: "center", of: swapId,
using: function(to) {
$(this).animate({
top: to.top,
left: to.left
}, ui.draggable.revertDuration, function() {
swapId.droppable('option', 'hasCoupon', true);
swapId.droppable('option', 'couponId', current);
current.draggable('option', 'dropId', swapId);
});
}
});
}
}
$(this).droppable('option', 'hasCoupon', true);
$(this).droppable('option', 'couponId', ui.draggable);
ui.draggable.draggable('option', 'dropId', $(this));
ui.draggable.position({ my: "center", at: "center", of: $(this),
using: function(to) { $(this).animate({ top: to.top, left: to.left }, 150 ); }
});
}
});
Примечание. Мы вручную устанавливаем значения для couponId / dropId в обратном вызове анимации для свопа, поскольку события перетаскивания фактически не запускаются в этой ситуации (вместо этого движение обрабатывается посредством вызова анимации jquery).
Я поэкспериментировал с использованием .trigger () первоначально для dragstart / dragstop, но они не вызывали событие drop, как я и предполагал.