Jquery:在 SortableList 和 DroppableArea 克隆问题之间链接的可拖动项目

Jquery : Draggable items linked between SortableList and DroppableArea clone issue

我正在制作一个由两部分组成的面板:

我正在尝试用 JQuery UI 来做那个行为。最重要的是,我希望能够将我的小部件从列表拖到该区域,如果需要,还可以将它们拖回列表。


编辑: https://jsfiddle.net/Tenmak/jzmsatrg/(新 link)

var myImageSlot = $("#image_slot").droppable({
    accept: ".listItem",
    drop: function(ev, ui) {
      console.log('dropped');

      if (ui.draggable.hasClass("ontray")) {
        var cloneTile = ui.draggable.clone()
            .removeClass("ontray")
          .removeClass("ui-sortable-handle")
          .show();
        myImageSlot.children(".itemsContainer").append(cloneTile);
        var dropx = ui.offset.left - myImageSlot.offset().left;
        var dropy = ui.offset.top - myImageSlot.offset().top;

        cloneTile.css({
          "left": dropx + "px",
          "position": "absolute",
          "top": dropy + "px"
        });
        setTileDraggable(cloneTile);
        ui.helper.remove();
        ui.draggable.remove();
      }
    }
  }).disableSelection();

通过在列表外为可拖动项目设置绝对位置,可以实现所需的行为,并且动画更流畅,但有时,很可能是因为 clone() 方法无法正常工作而导致重复。

有什么办法可以纠正这种有问题的行为吗?我应该采取不同的方式吗? 任何帮助都会非常好,我觉得我到了那里,但一些提示或任何东西真的很有帮助。 N.B : 我会尽快开放赏金,因为我真的需要这个。

我不得不从头开始,最后修改了大量代码。希望对你有帮助。

工作fiddle

https://jsfiddle.net/ergec/thj7sz0w/

html

<div class="master" id="master_containment">
    <div class="container sortables" id="listContainer">
        <div class="listItem">Item 1</div>
        <div class="listItem">Item 2</div>
        <div class="listItem">Item 3</div>
    </div>
    <div class="container" id="image_slot">
        <div class="itemsContainer sortables">
            <div class="listItem">Item 4</div>
            <div class="listItem">Item 5</div>
        </div>
    </div>
</div>

css

.sortable-placeholder {
    height: 60px;
    width: 60px;
    background-color: yellow;
    float: left;
}

.listItem {
    background: #00e;
    color: #fff;
    height: 60px;
    line-height: 60px;
    text-align: center;
    width: 60px;
    float: left;
    position: relative;
    z-index: 999;
}

.container {
    background: teal;
    border 1px;
    border-style: solid;
    width: 250px;
    height: 200px;
    padding: 10px;
}

#image_slot {
    background: brown;
    position: absolute;
    left: 300px;
    top: 8px;
}

.master {
    width: 560px;
    height: 220px;
}

.itemsContainer {
    height: 200px;
}

js

$("#listContainer").sortable({
    placeholder: "sortable-placeholder",
    containment: "#master_containment",
    connectWith: ".itemsContainer",
    revert: 100
}).find(".listitem").draggable({
    connectToSortable: ".sortables",
    containment: "#master_containment",
    helper: "original",
    revert: "invalid"
}).disableSelection();
$(".itemsContainer").sortable({
    placeholder: "sortable-placeholder",
    containment: "#master_containment",
    connectWith: "#listContainer",
    revert: 100
}).find(".listItem").draggable({
    connectToSortable: ".sortables",
    containment: "#master_containment",
    helper: "original",
    revert: "invalid"
}).disableSelection();

我希望我已经解决了您在删除后进行克隆时遇到的重复问题。

我发现的原因是,当您在容器之间快速拖放项目时,它会被克隆两次,因为放置事件出于某种原因调用了两次,因为最快的移动会触发它。

为了解决这个问题,我在数据属性的帮助下为负载上的每个可拖动项目设置了一个索引,并在将项目附加到容器时检查相同的索引是否已经存在任何相同的索引以避免重复。

然后我对此进行了很多测试,无法再重现该问题。所以我希望它解决了这个问题,但无论如何我需要你检查并确认:-)

这是更新后的 fiddle link,

https://jsfiddle.net/balasuar/jzmsatrg/4/

我做的修复是,

一种设置索引的方法

var setupItemIndex = function(index) {
     return function(container) {
        container.find(".listItem").each(function(){
                    $(this).attr('data-index', index++);
        });
     };
  }(0);

然后启动两个容器的索引设置,

setupItemIndex($('#listContainer'));
setupItemIndex($('#image_slot'));

然后检索掉落物品的索引,

  var targetContainer = myImageSlot.children(".itemsContainer");
  var itemIndex = ui.draggable.attr('data-index');

然后,在追加之前检查这个索引是否已经存在于正确的容器中。

if(targetContainer.has('[data-index="' + itemIndex + '"]').length === 0) {
        myImageSlot.children(".itemsContainer").append(cloneTile);

        -----

}

试一试:-)