如何在程序中终止jQuery拖动操作?

13

如何在程序中中止jQuery拖动操作?

使用jQuery UI,用户开始拖动操作。当拖动时,会发生异步事件导致拖动的元素被删除(例如基于计时器的刷新)。在刷新之前,我想在避免已删除元素的错误之前完成以下操作:

   element.trigger('dragstop');

但是那似乎没有起作用。


2
由于可拖动当前缺乏官方的取消命令方式,因此每个答案都将是一个包含各种不必要副作用的黑客。以下是功能请求票据:http://bugs.jqueryui.com/ticket/8414 - Brennan Roberts
4个回答

7

注意:从dragstart返回false也会取消拖动。 - Aaron

4
我添加这个答案是因为我正在寻找相同的问题,希望得到一个简短的答案。
只需在拖动事件中返回 false 即可。
虽然感谢您的长篇回答,但是我通过它们找到了自己的答案。

这似乎运行良好 - 为什么错误报告中有“wontfix”? [1] - http://bugs.jqueryui.com/ticket/8414 - sebhaase

2

按照jQuery UI的设计,拖动过程中官方不允许取消拖动[1] -- 我不太赞同这种情况,但事实就是这样。

如果你想要在拖动过程中可靠地取消拖动,你需要结合一些技巧[2, 3]:

$( window ).keydown( function( e ){
  if( e.keyCode == 27 ) {
    var mouseMoveEvent = document.createEvent("MouseEvents");
    var offScreen = -50000;

    mouseMoveEvent.initMouseEvent(
      "mousemove", //event type : click, mousedown, mouseup, mouseover, etc.
      true, //canBubble
      false, //cancelable
      window, //event's AbstractView : should be window
      1, // detail : Event's mouse click count
      offScreen, // screenX
      offScreen, // screenY
      offScreen, // clientX
      offScreen, // clientY
      false, // ctrlKey
      false, // altKey
      false, // shiftKey
      false, // metaKey
      0, // button : 0 = click, 1 = middle button, 2 = right button
      null // relatedTarget : Only used with some event types (e.g. mouseover and mouseout).
            // In other cases, pass null.
    );

    // Move the mouse pointer off screen so it won't be hovering a droppable
    document.dispatchEvent(mouseMoveEvent);

    // This is jQuery speak for:
    // for all ui-draggable elements who have an active draggable plugin, that
    var dragged = $('.ui-draggable:data(draggable)')
      // either are ui-draggable-dragging, or, that have a helper that is ui-draggable-dragging
      .filter(function(){return $('.ui-draggable-dragging').is($(this).add(($(this).data('draggable') || {}).helper))});

    // We need to restore this later
    var origRevertDuration = dragged.draggable('option', 'revertDuration');
    var origRevertValue = dragged.draggable('option', 'revert');

    dragged
      // their drag is being reverted
      .draggable('option', 'revert', true)
      // no revert animation
      .draggable('option', 'revertDuration', 0)
      // and the drag is forcefully ended
      .trigger('mouseup')
      // restore revert animation settings
      .draggable('option', 'revertDuration', origRevertDuration)
      // restore revert value
      .draggable('option', 'revert', origRevertValue);
  }
}

现在,这并不美观。但它能够工作。即使在悬停接受可放置对象时取消。

玩得开心。

[1] - http://bugs.jqueryui.com/ticket/8414
[2] - https://gist.github.com/3517765
[3] - https://forum.jquery.com/topic/how-to-cancel-drag-while-dragging


1
@FerRory所建议的那样,您可以利用drag事件。
您可以利用data()方法来确定一个元素是否可拖动:
$("div").draggable({
    drag: function() {
       return !$(this).data("disabledrag");
    },
    revert: true
});

然后在您的异步操作中,如果正在拖动的元素是已删除的元素(我假设您有一些将DOM元素与来自服务器的数据关联的系统),则可以设置该数据:

var $dragging = $(".ui-draggable-dragging");
if ($dragging.length) {
    // If this is the item that was deleted, stop dragging:
    if ($dragging.attr("id") === "item-one") {
        $dragging.data("disabledrag", true);
        $dragging.addClass("deleted").html("This item has been deleted!");            
    }
}

我已经更新了我的示例这里。第一个div将在5秒后被“删除”。


这将触发“stop”事件,但不会取消拖动。如果您将示例拖动修改为以下内容,则可以在拖动矩形时看到它:stop: function() { $('div').css('background-color','green').css('border', 'solid 1px black'); }, drag: function() { $('div').css('border', '');} - remack
@remack:好的,我误解了。您想把可拖动对象恢复到原来的位置吗? - Andrew Whitaker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接