Пользовательский интерфейс jQuery: как я могу отменить возврат сортируемого элемента при успешном перемещении на удаляемый элемент?

У меня есть список sortable, в котором есть несколько элементов, которые пользователь должен иметь возможность переупорядочивать.

В качестве альтернативы элементы также можно перетаскивать в 5 доступных зон сброса (droppable контейнера).

Проблема, с которой я сталкиваюсь, заключается в следующем: когда удаление успешно выполнено в зоне droppable, анимация возврата sortable все еще воспроизводится, анимируя удаленный элемент обратно в список sortable.

Вместо этого я хотел бы анимировать его таким образом, чтобы помощник брался из того места, где произошло drop, а затем анимировался в зону droppable, что-то вроде перетаскивания файла в корзину на Mac.

Однако, чтобы последний работал, мне нужно:

  1. При успешном сбросе остановите анимацию возврата.
  2. Скопируйте координаты перетаскиваемого элемента и запустите пользовательскую анимацию в центре перетаскиваемого элемента.

Проблема находится в части (1), draggable разрешает «недействительные» или «действительные» флаги для revert, но sortable нет.

Любые идеи о том, как я могу достичь этого?


person Jannis    schedule 17.12.2012    source источник


Ответы (1)


Итак, после некоторого времени назад и вперед, мне удалось решить эту проблему, клонировав исходный элемент ui.helper (который создает sortable) и используя этот клон (который, очевидно, не возвращается назад), чтобы закончить пользовательскую последовательность анимации, удалив оригинал помощник и заполнитель (созданный sortable), чтобы скрыть анимацию возврата sortable.

Это не так чисто, как мне бы хотелось, потому что я фактически все еще позволяю функции возврата sortable выполняться (а не отменять ее), но до тех пор, пока у кого-то не появится идея получше, это работает.

Код ниже:

// default sortable interaction/setup.
$('.sortable-list').sortable({
  placeholder: 'sortable-list__item sortable-list__item--placeholder',
  revert:      true,
  helper:      'clone',
  tolerance:   'pointer',
  connectWith: '.sortable-list',
  appendTo:    'body',
  zIndex:      1000
});

// dropzone interaction will grab the ui.helper from sortable clone it and then
// reuse it for it's own finish animation while removing the helpers from the
// sortable list and dom.
$('.dropzone')
  .droppable({
    accept:      '.sortable-list__item',
    hoverClass:  'dropzone--hover',
    activeClass: 'dropzone--active',
    tolerance:   'pointer'
  })
  .on('drop', function(event, ui) {
    var $item   = ui.draggable, // this is the original item.
        $helper = ui.helper;    // this is the cloned item the user drags

    // clone the helper instance and position it in the same exact spot where
    // the user had left it using the ui.position
    // (or ui.offset depending on your nesting/positioning of the helper)
    var $clone  = $helper.clone().css({ 
          "position": "absolute",
          "top":      ui.position.top,
          "left":     ui.position.left
        }).appendTo('body');

        // cleanup the original helper (remove from stage) and hide placeholder
        // elements. We're hiding the latter because the revert callback of 
        // sortable is removing it for us and will otherwise throw an error that
        // the placeholder can't be removed because it no longer exists in the DOM.
        $helper.remove();
        $('.sortable-list__item--placeholder').hide();

    // launch into your own animation sequence using the $clone of $helper
    // and process the drop data accordingly.

  });
person Jannis    schedule 20.12.2012