Подтвердить что ты не робот

JQuery Sortable - отмена и возврат не работает как ожидалось

Проблема (jsFiddle демонстрация проблемы)

У меня возникают проблемы с параметром revert при использовании в сочетании с методом cancel в сортировке jQuery. Метод отмены, описанный в jQuery Sortable documentation, гласит:

Отменяет изменение текущей сортировки и возвращает ее обратно до начала текущего сортировки. Полезно для остановки и получения функции обратного вызова.

Это отлично работает как в обратных вызовах stop, так и receive, однако, если я добавлю продолжительность revert в сортируемый список подключений, он начинает действовать смешно (см. jsFiddle здесь).

В идеале, при отмене, revert может просто не произойти, или, альтернативно, в более идеальном мире, он изящно вернется к нему в оригинальном месте. Любые идеи, как я могу заставить revert и cancel играть хорошо?

Ожидаемые

  • Перетащите из списка слева в правый список.
  • Удалить элемент
  • Элемент анимируется в оригинальном месте - или - немедленно переходит в исходное местоположение

Фактические

  • Перетащите из списка слева в правый список.
  • Удалить элемент
  • Элемент анимируется в новом месте, предполагая, что сортировка успешна.
  • Пункт немедленно переходит в исходное местоположение, поскольку сортировка отменена

Разъяснение

Свойство revert перемещает элемент в место, где элемент упадет в случае успеха, а затем сразу же вернется в исходное местоположение из-за revert, встречающегося перед методом cancel. Есть ли способ изменить жизненный цикл, поэтому, если выполняется cancel метод, revert нет, и вместо этого элемент немедленно возвращается к исходному местоположению?

4b9b3361

Ответ 1

Спустя много часов для поиска решения я решил, что единственный способ добиться того, что я пытался сделать, - изменить способ, с помощью которого сортируемый плагин jQuery зарегистрировал время возврата. Цель состояла в том, чтобы позволить свойству revert принимать не только boolean или integer, но и принимать function. Это было достигнуто путем легкого подключения к prototype на ui.sortable и выглядело примерно так.

jQuery Сортируемое исправление

$.ui.sortable.prototype._mouseStop = function(event, noPropagation)
{
    if (!event) return;

    // if we are using droppables, inform the manager about the drop
    if ($.ui.ddmanager && !this.options.dropBehaviour)
        $.ui.ddmanager.drop(this, event);

    if (this.options.revert)
    {
        var self = this;
        var cur = self.placeholder.offset();

        // the dur[ation] will not determine how long the revert animation is
        var dur = $.isFunction(this.options.revert) ? this.options.revert.apply(this.element[0], [event, self._uiHash(this)]) : this.options.revert;

        self.reverting = true;

        $(this.helper).animate({
            left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
            top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
        }, !isNaN(dur) ? dur : 500, function ()
        {
            self._clear(event);
        });
    } else
    {
        this._clear(event, noPropagation);
    }

    return false;
}

Реализация

$('ul').sortable({
    revert: function(ev, ui)
    {
        // do something here?
        return 10;
    }
});

Ответ 2

я создал демо для вас здесь:

код jsfiddle

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

я изменил метод обратного вызова приема:

$(ui.sender).sortable('cancel');

:

$(ui.sender).sortable( "option", "revert", false );

надеюсь, это то, что вы ожидали.

Ответ 3

Я закончил создание нового события с именем beforeRevert, которое должно возвращать true или false. Если false, то вызывается функция отмены, и элемент возвращается в исходное положение. Я не кодировал это с помощью вспомогательной опции, поэтому для ее поддержки, вероятно, потребуется дополнительная работа.

jQuery Сортировка Hotfix с анимацией

var _mouseStop = $.ui.sortable.prototype._mouseStop;
$.ui.sortable.prototype._mouseStop = function(event, noPropagation) {
  var options = this.options;
  var $item = $(this.currentItem);
  var el = this.element[0];
  var ui = this._uiHash(this);
  var current = $item.css(['top', 'left', 'position', 'width', 'height']);
  var cancel = $.isFunction(options.beforeRevert) && !options.beforeRevert.call(el, event, ui);

  if (cancel) {
    this.cancel();
    $item.css(current);
    $item.animate(this.originalPosition, {
      duration: isNaN(options.revert) ? 500 : options.revert,
      always: function() {
        $('body').css('cursor', '');
        $item.css({position: '', top: '', left: '', width: '', height: '', 'z-index': ''});
        if ($.isFunction(options.update)) {
          options.update.call(el, event, ui);
        }
      }
    });
  }

  return !cancel && _mouseStop.call(this, event, noPropagation);
};

Реализация

$('ul').sortable({
  revert: true,
  beforeRevert: function(e, ui) {
    return $(ui.item).hasClass('someClass');
  }
});