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

时间:2009-08-30 06:32:22

标签: jquery jquery-ui drag-and-drop

我有两个div.containers。两个容器都有div.item。使用jQuery,我如何通过drag& amp;交换div.item元素?下降?这两个元素都应该能够重新交换。

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

...谢谢

6 个答案:

答案 0 :(得分:3)

@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)
                );
        }
    });

});

答案 1 :(得分:2)

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

注意:您还需要在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 );

最后,设置你的拖拉机& droppables ...当您设置droppable时,使用jquery UI的位置助手来帮助交换可拖动的...

$('.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(),但他们并没有像我想象的那样触发掉落事件。

答案 2 :(得分:2)

也许我错过了什么,但我认为我有一个更简单的解决方案:

$('.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. 此时可拖动项目的位置会很奇怪,因为我们已从页面中删除了元素并重新添加它们,因此请重置其位置。

答案 3 :(得分:1)

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

$(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)
            );
        }
    });
});

希望,有人可以改善这个......:)

...欢呼

答案 4 :(得分:1)

    $(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 chan编码并经过验证

答案 5 :(得分:0)

我在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;
};