13

问题(问题的jsFiddle演示

当与jQuery sortable 中revert的方法结合使用时,我在设置方面遇到了一些问题。jQuery Sortable 文档cancel中记录的取消方法指出:

取消当前可排序的更改并将其恢复到当前排序开始之前的状态。在停止和接收回调函数中很有用。

这在回调stopreceive回调中都可以正常工作,但是如果我向可排序的连接列表添加revert 持续时间,它就会开始变得有趣(请参阅此处的 jsFiddle)。

理想情况下,取消后,它revert根本不会发生,或者在更理想的世界中,它会优雅地恢复到原来的位置。revert有什么想法可以让我cancel玩得更好吗?

预期的

  1. 从左侧列表拖动到右侧列表
  2. 掉落物品
  3. 项目动画到原始位置- 或 -立即转移到原始位置

实际的

  1. 从左侧列表拖动到右侧列表
  2. 掉落物品
  3. 假设可排序成功,项目动画到新位置
  4. 项目立即转移到原始位置,因为可分类已被取消

澄清

如果成功,该属性会将项目移动到该项目将下降的位置,然后由于该方法之前发生的revert原因立即移回原始位置。有没有办法改变生命周期,所以如果方法被执行,不是,而是项目立即返回到它的原始位置?revertcancelcancelrevert

4

3 回答 3

5

我在这里为您创建了一个演示:

jsfiddle 代码

它似乎产生了您期望的输出。

我从这里更改了接收回调方法:

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

对此:

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

希望这是您所期望的。

于 2012-06-19T16:10:20.103 回答
5

在寻找解决方案数小时后,我决定实现我想要做的事情的唯一方法是修改 jQuery 可排序插件注册恢复时间的方式。目的是允许该revert属性不仅接受 a booleanor integer,而且还接受 a function。这是通过非常轻松地连接到prototypeon来实现的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;
    }
});
于 2012-06-21T08:53:27.440 回答
0

我最终创建了一个名为 beforeRevert 的新事件,它应该返回 true 或 false。如果为 false,则调用取消函数并将项目动画回其原始位置。我没有考虑到 helper 选项对此进行编码,因此它可能需要一些额外的工作来支持它。

带有动画的 jQuery 可排序修补程序

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');
  }
});
于 2013-12-20T03:28:50.813 回答