Как программно прервать операцию перетаскивания jQuery?

Как программно прервать операцию перетаскивания jQuery?

Используя jQuery UI, пользователь начинает операцию перетаскивания. При перетаскивании происходит асинхронное событие, которое заставляет удаленный элемент удаляться (например, обновление на основе таймера). В обновлении я хотел бы сделать что-то вроде этого перед обновлением, чтобы избежать ошибок из удаленного элемента:

   element.trigger('dragstop');

Но это, похоже, не сработало.

Ответ 1

Это можно сделать, используя функцию обратного вызова (возврат false) события перетаскивания или перетаскивания. См. http://jqueryui.com/demos/draggable/#event-drag

Ответ 2

Как @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 секунд.

Ответ 3

Официальное отмена перетаскивания при перетаскивании не допускается в пользовательском интерфейсе jQuery "по дизайну" [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 AbstractView : should be window
      1, // detail : Event 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);
  }
}

Теперь это некрасиво. Но это работает. Даже при отмене при падении принимающего droppable.

Удачи с ним.

[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

Ответ 4

Я добавляю этот ответ, когда искал ту же проблему, и мне нужен короткий ответ.

Просто верните false в событие перетаскивания.

Спасибо вам за длинный ответ, хотя, поскольку я нашел их через них.