如果嵌套的 droppable 在特定情况下不接受 draggable,则不会传播 Over 事件

Over event isn't propagated if nested droppable doesn't accept draggable under a certain scenario

以下步骤适用于下面分享的jsFiddle

步骤:

  1. 点击并拖动 Draggable 1 到 Droppable 3 的内部 droppable 上。继续按住 Draggable 1,不要松开它。
  2. 请注意,当 Draggable 1 在内部 droppable 上并且指针完全覆盖 Droppable 3 区域时,外部 Droppable 3 会突出显示,这是预期的。
  3. 将 Draggable 1 移到 Droppable 3 的边界之外并释放它,使其完全停留在空白区域。
  4. 单击并拖动 Draggable 2。您只需将其拖动到某个随机空白点,而不是 droppable。
  5. 发布 Draggable 2.
  6. 再次抓住 Draggable 1 并将其拖到 Draggable 3 的内部 droppable 上。继续按住 Draggable 1,不要松开它。
  7. 当 Draggable 1 在内部 droppable 上并且指针完全位于 Droppable 3 的区域上时,记下外部 Droppable 3 容器的状态。

预期结果:

实际结果:

备注:

相关问题:

我问这个问题是因为它似乎与以下 Whosebug 问题有些相关,但我的情况略有不同。也许它具有相同的根本原因,但可能有不同的解决方法?

jsFiddle:

https://jsfiddle.net/deepankarj/60zz9zgb/

$(function() {
    $("#draggable, #draggable2").draggable({
        cursor: "move",
        cursorAt: {
            top: 0,
            left: 0
        },
    });

    function logEventId(prefix, event) {
        console.log(prefix + ": " + event.target.id); 
    }
    function createLogEventIdFunction(handlerName) {
        return function(event, ui) {
            logEventId(handlerName, event);
        }
    }

    $("#droppable, #droppable-inner").droppable({
        activeClass: "ui-state-hover",
        hoverClass: "ui-state-active",
        tolerance: "pointer",
        over: createLogEventIdFunction("over"),
        out: createLogEventIdFunction("out"),
        drop: function(event, ui) {
            logEventId("drop", event);
            $(this)
                .addClass("ui-state-highlight")
                .find("> p")
                .html("Dropped!");
            return false;
        }
    });

    function decorateWithDroppable(selector, greedy, canAccept, over) {
        canAccept = !!canAccept ? canAccept : function(element) {
            console.log("canAccept: this: " + $(this).attr("id") + ", el: " + element.attr("id") + ", result: true");
            return true;
        };

        over = !!over ? over : createLogEventIdFunction("over");

        $(selector).droppable({
            greedy: greedy,
            activeClass: "ui-state-hover",
            hoverClass: "ui-state-active",
            tolerance: "pointer",
            accept: canAccept,
            over: over,
            out: createLogEventIdFunction("out"),
            drop: function(event, ui) {
                logEventId("drop", event);
                $(this)
                    .addClass("ui-state-highlight")
                    .find("> p")
                    .html("Dropped!");
            }
        });
    };

    decorateWithDroppable("#droppable2, #droppable2-inner", true);
    decorateWithDroppable("#droppable3", true);
    decorateWithDroppable("#droppable3-inner", true, function canAccept(element) {
        console.log("canAccept: this: " + $(this).attr("id") + ", el: " + element.attr("id") + ", result: " + (element.attr("id") !== "draggable"));    
        return (element.attr("id") !== "draggable");
    });

});

在初始化 draggable 时将 refreshPositions 设置为 true 对我有用。这是示例代码。

jQuery().draggable({
    ....    
    refreshPositions: true
    ....
});