如何用jQuery UI交换元素draggable和droppable?

我有两个div.containers。 两个容器都有div.item。 使用jQuery,如何通过拖放交换div.item元素? 两个元素都应该能够重新交换。

有没有简单的方法来做到这一点?

谢谢…

@Ei Maung ..

我从你的肮脏解决方案得到了顺利的解

$(document).ready(function () { src = null; options = { revert:true, /*axis: 'x',*/ opacity: 0.8, start: function() { src = $(this).parent(); } }; $(".item").draggable(options); $(".container").droppable({ drop: function(event, ui) { src.append( $('.item', this).remove().clone() .removeClass().addClass("item") .css({"left": '', "opacity": '',"top":''}) .draggable(options) ); $(this).append( ui.draggable.remove().clone() .removeClass().addClass("item") .css({"left": '', "opacity": '',"top":''}) .draggable(options) ); } }); }); 

也许有点晚了,但我认为这是一个更好的解决方案…如果其他人发现这个有用,会发布文档/搜索目的

注意:您还需要在UI构建中加载jQuery UI的Position元素才能使此解决方案正常工作。

在我的例子中,我正在创建一组可拖动的“优惠券”,可以放置在不同的位置。 在给定时间,只有一张优惠券可以放置在任何可放置的区域。

为了管理优惠券分配到可放置区域,我创建了一些帮助对象,我将用它来扩展可拖动和可放置原型的选项对象:

 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动画调用来处理的)。

我最初在dragstart / dragstop上使用.trigger(),但他们并没有像我认为的那样触发掉落事件。

也许我错过了一些东西,但我想我有一个更简单的解决方案:

 $('.droppable').droppable({ drop: function (event, ui) { ui.draggable.parent().append($(this).children()); $(this).append(ui.draggable); ui.draggable.css({ left: '', top: '' }); } }); 

简而言之:

  1. 当可拖动项目放在可放置区域中时,获取可拖动项目的(上一个)父元素。
  2. 从可放置区域中删除子项并将它们附加到可拖动项目的父元素。
  3. 从其(上一个)父元素中删除可拖动项目,并将其附加到放置它的可放置区域。
  4. 此时可拖动项目的位置将是奇怪的,因为我们已从页面中删除元素并重新附加它们,因此重置其位置。

好的,我得到了肮脏的解决方案……

 $(document).ready(function () { src = null; options = { revert:true, axis: 'x', opacity: 0.8, start: function() { src = $(this).parent(); } }; $(".item").draggable(options); $(".container").droppable({ drop: function(event, ui) { src.append( $('.item', this).remove().clone() .removeClass().addClass("item") .css({"left": '', "opacity": ''}) .draggable(options) ); $(this).append( ui.draggable.remove().clone() .removeClass().addClass("item") .css({"left": '', "opacity": ''}) .draggable(options) ); } }); }); 

希望,有人可以改善这个… 🙂

欢呼…

  $(function () { $('#sortable').sortable({ start: function (e, ui) { // creates a temporary attribute on the element with the old index $(this).attr('data-previndex', ui.item.index()); }, update: function (e, ui) { // gets the new and old index then removes the temporary attribute newIndex = ui.item.index(); oldIndex = $(this).attr('data-previndex'); $(this).removeAttr('data-previndex'); tempNew = newIndex - 1; tempoldIndex = oldIndex; if (oldIndex > newIndex) { tempNew = newIndex + 1; $("#sortable li:eq(" + tempNew + ")").insertAfter($("#sortable li:eq(" + tempoldIndex + ")")); } else { $("#sortable li:eq(" + tempNew + ")").insertBefore($("#sortable li:eq(" + tempoldIndex + ")")); } } }); }); 

//由ubaidullah陈编码并经过validation

我在pengoworks找到了这个解决方案:

 jQuery.fn.swap = function(b) { b = jQuery(b)[0]; var a = this[0]; var t = a.parentNode.insertBefore(document.createTextNode(''), a); b.parentNode.insertBefore(a, b); t.parentNode.insertBefore(b, t); t.parentNode.removeChild(t); return this; };