jQuery UI 的贪婪 droppable 无法按预期工作

Posted

技术标签:

【中文标题】jQuery UI 的贪婪 droppable 无法按预期工作【英文标题】:jQuery UI's greedy droppable not working as expected 【发布时间】:2018-10-29 02:44:57 【问题描述】:

我有一个可以拖放到 droppable 中的可拖动对象列表,当这种情况发生时,可拖动对象被克隆并转换为可拖放对象。

这个新的 droppables 是贪婪的,但是当它们接收到一个可拖动对象时,两个 drop 事件都会被触发(来自可拖动对象的 drop 事件和来自可放置区域的 drop 事件)

我做错了什么?我需要事件只触发一次(从新的 droppable 中)

这是一个fiddle:将一个项目拖放到红色区域,然后将另一个项目拖放到您已经拖放的项目中。查看控制台日志。

html

<div id="main_droppable"></div>

<ul>
  <li class="item" data-id="1">1</li>
  <li class="item" data-id="2">2</li>
  <li class="item" data-id="3">3</li>
  <li class="item" data-id="4">4</li>
  <li class="item" data-id="5">5</li>
</ul>

JS

$(".item").data("active", false);

$(".item").draggable(
    helper: "clone",
    appendTo: "#main_droppable",
    scroll: false,
    start: function(event, ui)
    
        if($(this).data("active") == false)
        
            $(this).fadeTo(100, 0.2);
        
        else
        
            return false;
        
    ,
    revert: function(is_valid_drop)
    
        if(!is_valid_drop)
        
            $(this).fadeTo(100, 1).data("active", false);

            return true;
        
        else
        
            $(this).data("active", true);
        
    
);

$("#main_droppable").droppable(
    drop: function(event, ui)
    
        console.log("drop main");

        addNewItem(ui.helper);

        return false;
    
);

function addNewItem($oldItem)

    var $newItem = $oldItem.clone(false).fadeTo(100, 1).data("active", true);

    $oldItem.remove();

    $newItem.draggable(
        containment: "parent",
    );

    $newItem.droppable(
        greedy: true,
        drop: function(event, ui)
        
            console.log("drop item");

            $(this).fadeTo(100, 0, function()
            
                var $originalItem = $("ul").find(".item[data-id=" + $(this).data("id") + "]");

                $originalItem.fadeTo(100, 1).data("active", false);

                $("#main_droppable").find(".item[data-id=" + $originalItem.data("id") + "]").remove();
            );

            addNewItem(ui.helper);
        
    );

  $("#main_droppable").append($newItem);

CSS

#main_droppable

  border: 1px solid red;
  min-height: 50px;


.item

  display: inline-block;
  border: 1px solid blue;
  width: 25px;
  height: 25px;

【问题讨论】:

所以如果你做了重叠放置,项目不应该再次移回可拖动对象? @TarunLalwani 为什么不应该这样做?此外,重点是双落事件 我从未使用过 droppables,所以只是想了解问题所在,并了解您希望看到的预期行为是什么? 如果我对@Matias Canepa 的理解正确,您希望蓝色的可拖动对象也成为可放置对象,这样您就可以在视觉上嵌套可放置对象吗? @RobertUdah 有点……可拖动对象确实转换为可放置对象。但他们并不贪婪,我希望他们如此 【参考方案1】:

嗯...它与特定的类有关...

当我放下可拖动对象并克隆它时,ui-draggable-dragging 类保持在原位。因此,为了使其正常工作,我必须将其删除,然后一切都按预期工作。

我改变这一行:

var $newItem = $oldItem.clone(false).fadeTo(100, 1).data("active", true);

进入这个:

var $newItem = $oldItem.clone(false).fadeTo(100, 1).data("active", true).removeClass("ui-draggable-dragging");

更新小提琴:https://jsfiddle.net/3118zjg1/1/

【讨论】:

【参考方案2】:

我认为可拖动对象实际上变得贪婪,但#main_droppable 事件仍然被触发,因为:

当您将另一个.item 元素放在另一个元素之上时,将触发将.item 放入另一个.item 的预期操作。

    $newItem.droppable(
            greedy: true,
            drop: function(event, ui)
            
                console.log("drop item");
                ...

但是这个原始元素无论如何都会在代码的下方被删除..

    $(this).fadeTo(100, 0, function()
       
        var $originalItem = $("ul").find(".item[data-id=" + $(this).data("id") + "]");

        $originalItem.fadeTo(100, 1).data("active", false);

        $("#main_droppable").find(".item[data-id=" + $originalItem.data("id") + "]").remove();
        ...

您实际上是用新项目替换了原始项目,因此触发了#main_droppable 事件。

我不能说我知道如何在不改变您的预期行为的情况下解决无意的副作用,但希望您能更好地了解为什么 greedy 属性似乎不起作用。

【讨论】:

以上是关于jQuery UI 的贪婪 droppable 无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

02 Jquery UI Droppable 放置插件

使用 jquery-ui droppable 时,如何从 droppable 区域中删除已经删除的项目?

jQuery UI (Droppable):如果 droppable 具有相对/绝对的 css 位置,则可拖动元素不会放置在鼠标指针处

如何使 jQuery UI droppable hoverClass 仅适用于可拖动对象?

如何在 jQuery UI 中使用 Draggable 和 Droppable 将拖动的 li 添加到可放置的 ui 中?

使用 .droppable 拖放到 div 中时,jQuery UI 删除元素