【问题标题】:How to swap 2 items using Draggable and Droppable?如何使用 Draggable 和 Droppable 交换 2 个项目?
【发布时间】:2013-11-28 15:37:44
【问题描述】:

问题

我有 4 张图片。用户可以将它们拖放到另一个列表并更改图像的顺序。目标是用户选择图像的顺序。问题是当它们彼此放置时我无法交换这些图像。

HTML

<ul id="choices">
    <li><img src="http://placehold.it/200x200&text=1" /></li>
    <li><img src="http://placehold.it/200x200&text=2" /></li>
    <li><img src="http://placehold.it/200x200&text=3" /></li>
    <li><img src="http://placehold.it/200x200&text=4" /></li>
</ul>

<ul id="answers">
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>

jQuery

​​>
(function ($) {

    $("#choices li img").draggable({
        revert: true,
        zIndex: 10,
        snap: "#answers li",
        snapMode: "inner",
        snapTolerance: 40
    });

    $("#answers li").droppable({
        drop: function (event, ui) {
            var dropped = ui.draggable;
            var droppedOn = this;

            if ($(droppedOn).children().length > 0) {
                alert("I need to swap these");
            }

            $(dropped).detach().css({
                top: 0,
                left: 0
            }).prependTo($(droppedOn));
        }
    });
})(jQuery);

CSS(不是很重要)

img {
    display: block;
    z-index: 3;
}
#choices, #answers {
    display:block;
    padding: 0;
    margin: 0;
}
#choices li, #answers li {
    display: inline-block;
    height: 200px;
    width: 200px;
    margin: 10px;
    background: #515151;
}
#answers li {
    position: relative;
}

示例

http://jsfiddle.net/K6QNg/

【问题讨论】:

  • 在我继续审查之前,我只是想让你知道'choises' 有一个'c' 哈哈,而且你使用 Sizzle 遍历 DOM 的方式比必要的要多。 $("#choises li img") 应该是 var $img = $('#choices').find('img');
  • @Deryck 谢谢你:)
  • @Deryck 甚至可以更快,这只是一个例子:) jsPerf
  • @Bondye 哈哈好吧,我不喜欢吹牛,但是嗯……我的 Chrome 31 比其他所有的加起来都长。大声笑
  • 请查看我的回答 ;)

标签: jquery jquery-ui jquery-ui-draggable jquery-ui-droppable


【解决方案1】:

我的解决方案可能不是最优雅的(也许有人可以提供更直观的东西?),但它似乎有效;)

小提琴:http://jsfiddle.net/W9Z46/14/

(function ($) {
    var lastPlace;

    $("#choises li img").draggable({
        revert: true,
        zIndex: 10,
        snap: "#answers li",
        snapMode: "inner",
        snapTolerance: 40,
        start: function (event, ui) {
            lastPlace = $(this).parent();
        }
    });

    $("#answers li").droppable({
        drop: function (event, ui) {
            var dropped = ui.draggable;
            var droppedOn = this;

            if ($(droppedOn).children().length > 0) {
                $(droppedOn).children().detach().prependTo($(lastPlace));
            }

            $(dropped).detach().css({
                top: 0,
                left: 0
            }).prependTo($(droppedOn));
        }
    });
})(jQuery);

如您所见,我只是将您开始拖动的位置保留在变量 lastPlace 中,然后当您放下并检查某些东西时,将其放置在您之前开始拖动的位置。

【讨论】:

    【解决方案2】:

    我也遇到了同样的问题。但是我的代码有点不同。

        $(document).ready(function(){
        var x=[60,270,480];
        var y=[170,170,170];
    
        $(".draggable").draggable({
            revert:"invalid",
            start:function(){
    
            }
        });
    
        $(".droppable").droppable({
            accept:".draggable",
            hoverClass:"active",
            drop:function(ev,ui){
                if($(this).attr("name")!=null){
                   var d=$(this).attr("name");
                   var dgid=$(ui.draggable).attr("data-id")-1;
                   $("#"+d).animate({left:x[dgid],top:y[dgid]});
                   $("#drop"+$(ui.draggable).attr("data-id")).attr("name",$(this).attr("name"));
                   $("#"+d).attr("data-id",$(ui.draggable).attr("data-id"));
                }
                var dpid=$(this).attr("data-id")-1;
                $(this).attr("name",$(ui.draggable).attr("id"));
                $(ui.draggable).attr("data-id",$(this).attr("data-id"));
                $(ui.draggable).animate({left:x[dpid],top:y[dpid]},300);
            }
        });
    });
    

    查看Fiddle

    【讨论】:

      【解决方案3】:

      您可能应该尝试使用sortable,而不是在接收列表中放置droppable。这应该为您提供您正在寻找的功能。

      【讨论】:

      • 这真的回答了这个问题吗?
      • 我真的认为这是要走的路。这是此功能的正确插件。去年我不得不做一些类似的事情,我也尝试使用 droppable,但是那个插件没有优雅的解决方案。我最终使用了 sortable,它已经处理了从其他列表接收项目,并为您提供了交换元素的可能性(因为这是该插件的全部目的)。
      • 您可能需要查看Answering
      • 虽然我通常也会对实际上没有回答所问问题的答案皱眉,但在这种情况下,我认为这是一个相关的考虑因素。他本质上是使用可拖动/可放置来重新创建可排序的行为,并且考虑到他显然已经在使用 jQueryUI,切换交互可能并不困难。我认为它至少值得一提,即使它可能被认为是题外话。
      猜你喜欢
      • 2011-07-26
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 2018-07-16
      • 1970-01-01
      • 1970-01-01
      • 2012-01-14
      • 2018-04-05
      相关资源
      最近更新 更多