jQuery Draggable + Sortable - 如何拒绝放入排序?

Posted

技术标签:

【中文标题】jQuery Draggable + Sortable - 如何拒绝放入排序?【英文标题】:jQuery Draggable + Sortable - How to reject a drop into the sort? 【发布时间】:2011-10-30 19:04:39 【问题描述】:

我有一个可排序的视频列表和一组可拖动的视频。基本上我想确保拖入的视频不在视频的前 5 分钟。由于视频长度不同,我想在 drop 上进行测试 - 将时间加起来,如果不是 5 分钟,则恢复并显示错误。

我已经尝试连接到所有可拖动和可排序的回调(包括未记录的还原回调)来进行测试,但无论我尝试什么,dom 总是会发生变化(并且可排序调用它的更新回调)...

有人有什么建议吗?

【问题讨论】:

【参考方案1】:

您可以通过调用draggable 小部件的cancel 方法来恢复拖动操作(该方法未记录在案,但其名称不以下划线开头,这可以说使其“更安全”以可靠地使用)。不过,它仅在 start 事件期间有效,因为其他事件发生得太晚而无法触发还原动画。

但是,sortable 小部件即使取消拖动操作仍然会注册一个放置,因此您还必须删除新添加的项目(在stop 事件期间,因为start 事件也会发生早):

$("#yourSortable").sortable(
    start: function(event, ui) 
        if (!canDropThatVideo(ui.item)) 
            ui.sender.draggable("cancel");
        
    ,
    stop: function(event, ui) 
        if (!canDropThatVideo(ui.item)) 
            ui.item.remove();
            // Show an error...
        
    
);

您可以在this fiddle 中查看结果(第四项将始终还原)。

更新:正如 John Kurlak 在 cmets 中正确指出的那样,该项目不会因为调用 draggable("cancel") 而恢复,而是因为在我们的例子中 ui.sendernull。投掷任何东西都会导致相同的行为。

唉,我尝试的所有其他组合都导致项目在没有动画发生的情况下被还原,所以也许我们最好的选择是避免访问ui.sender,而是写如下内容:

start: function(event, ui) 
    if (!canDropThatVideo(ui.item)) 
        throw "cancel";
    

不过,未捕获的异常仍会出现在控制台中。

【讨论】:

您好,谢谢您的回答!我正在努力让它工作 - 测试(canDropThatVideo)需要找到它被丢弃在列表中的位置,以便它可以与相邻的视频进行比较。我尝试了类似的方法: // 获取相邻的 vids var nextVid = $(ui.item).next(); var prevVid = $(ui.item).prev();但这些似乎没有得到正确的 - 可能是因为它在开始事件中......应该工作吗? @user612911,它更复杂,但它可以工作。您必须绑定到sort 事件而不是start 并分别使用ui.placeholder.next()ui.placeholder.prev()。您可能还必须以某种方式记住您对该项目做出的决定(可能使用data()),以便stop 处理程序知道要做什么。 (顺便说一句,您不需要在 ui 成员上调用 $():它们已经是 jQuery 对象。) 太好了,我现在运行良好。我还在可拖动的start 事件中附加了一些逻辑,以将一些“cantDropHere”类添加到无效放置空间的元素中,然后从可排序中排除这些类。谢谢! ui.sender 在您的代码示例和 JSFiddle 中似乎为空...我认为当元素来自可拖动而不是另一个可排序时它为空。 @FrédéricHamidi 它有效,但仍然抛出错误。我认为当发生错误时,可拖动事件会取消事件(或者某些代码不会执行以允许放置它)。我会检查 jQuery 源代码。您可以轻松地将ui.sender.draggable("cancel"); 替换为blah,它仍然有效。【参考方案2】:

我找到了另一种方式。如果你不介意让它的动画飘回原来的位置,你可以随时使用它

.droppable(
    drop: function (event, ui) 

        var canDrop = false;

        //if you need more calculations for
        //validation, like me, put them here

        if (/*your validation here*/)
            canDrop = true;

        if (!canDrop) 
            ui.draggable.remove();
        
        else
            //you can put whatever else you need here
            //in case you needed the drop anyway
        
    
).sortable(
    //your choice of sortable options
);

我使用这个是因为我需要 drop 事件。

【讨论】:

以上是关于jQuery Draggable + Sortable - 如何拒绝放入排序?的主要内容,如果未能解决你的问题,请参考以下文章

获取 JQuery ui.draggable 的属性

jQuery 令人不快的 Draggable, Resizable 交互

jquery如何通过'draggable'和'droppable'来排序't项目“互相吃”?

jQuery Draggable,将位置转换为百分比

jQuery Draggable 包含可见窗口?

jQuery(...)。draggable不是一个函数