【问题标题】:jQuery-UI sortable: Animate from original position to new after helper dropjQuery-UI 可排序:在助手删除后从原始位置动画到新位置
【发布时间】:2014-01-31 10:59:56
【问题描述】:

TLDR

我希望能够在帮助器被删除后通过显示原始项目移动到它的新位置而其他项目移动来为我的 jQuery-UI 排序设置动画。由于某些需要固定在适当位置的可分类物,这使情况变得复杂。

项目:

该项目涉及在选项卡式界面中动态生成的 jQuery-UI portlet。选项卡和 portlet 内容本身是通过对已建立的 Web 服务的异步 AJAX 请求生成的。每个选项卡中都有数量不定的 portlet,并使用自定义滚动条进行内容显示。我已经使用类和在堆栈溢出的其他地方找到的解决方案(稍作修改)实现了某些 portlet 的修复。当前功能的一个非常基本的实现可以在这里看到:http://jsfiddle.net/99yVq/

问题

在实现 portlet 修复之前,我在通过显示和隐藏占位符元素进行排序时制作动画:

$( ".content" ).sortable({       
    start: function(e, ui){
        $(ui.placeholder).hide(300);
    },
    change: function (e,ui){
        $(ui.placeholder).hide().show(300);
    }
});

可在此处查看:http://jsfiddle.net/BWNE2/。这工作得相当好,但我觉得动画很不稳定,显然需要一些戳才能让它与上面的 portlet 修复解决方案一起工作(因为它依赖于帮助程序创建来确定固定位置)。这不是我正在寻找的解决方案。

更新

是否将两者结合起来(没有真正需要的警告)并且组合功能可在此处获得:http://jsfiddle.net/BWNE2/1/。动画可以工作,但您可以看到 .fixed portlet 与其他 portlet 一起动画,然后恢复到原来的位置。

更新结束

问题

我的理想方案是让用户将 portlet 助手(我相信它是在拖动过程中使用的原始项目的克隆)从其原始位置拖动到新位置。在删除portlet 时,将从旧位置动画到新位置。排序过程中的当前移动应该保持给最终用户反馈,但最终的动画应该在助手下降之后发生。

有人对如何实现这一目标有任何想法或示例吗?

如果我的问题格式不充分,或者您需要更多信息,请告诉我。

提前致谢。

编辑

您可以在此处看到:http://jsfiddle.net/BWNE2/2/ 将其固定在位置 3(顶部的右上角)时,动画效果更加不足。排序时它通常不在正确的位置,尽管它确实在排序结束时恢复到正确的位置。

【问题讨论】:

  • 没有想法或者我需要澄清问题吗?
  • 所以,是的,我不确定我是否完全理解你的意图。所以即使当你拖动它时,当你放下 portlet 时它会动画(随机移动 portlet),你希望它显示出来回到它开始的地方,然后动画到它被放下的地方?
  • 老实说,我不明白问题出在哪里。你能用一两句话具体说明你的问题吗?为什么jsfiddle.net/BWNE2 不是一个好的解决方案?似乎工作正常。 :)
  • 作为一种解决方案,它可以工作,但这不是我想要的功能。正如@Trevor 所说,我希望portlet 在助手被删除后从它的起始位置平滑地动画到它的新位置。我现在正试图找到一个例子。

标签: javascript jquery jquery-ui jquery-ui-sortable


【解决方案1】:

按照找到的解决方案in other question,基本上是在拖动您克隆itens并将它们动画到新位置时,我将其合并到您的代码中。

这段代码没有的是发布后的动画,我通过在mouseup事件上保存位置,并将拖动的元素动画到最终位置来制作。

最终小提琴:http://jsfiddle.net/hTgad/

代码:

var lastPosition;

$( "#content" ).sortable({
    delay: 100,
    distance: 10,
    handle: '.portlet-header',
    items: '.portlet:not(.fixed)',
    start: function(e, ui)
    {
        //store the fixed itens position
        $('.fixed', this).each(function(){
            var $this = $(this);
            $this.data('pos', $this.index());
        });

        // Identify the item being dragged
        ui.helper.addClass("being-dragged");

        var clonedItems = $("#cloned_items");

        // Create a clone for every item, except the fixed ones and the one being dragged            
        $("#content .portlet:not(.being-dragged, .ui-sortable-placeholder, .fixed)").each(function(){
            // clone the original items to make their
            // absolute-positioned counterparts...
            var original = $(this);
            var clone = original.clone();
            // 'store' the clone for later use...
            original.data("clone", clone);
            original.css("visibility", "hidden"); // Hide the original

            // set the initial position of the clone
            var position = original.position();
            clone.css("left", position.left)
                 .css("top", position.top);

            // append the clone...
            clonedItems.append(clone);
        });
    },
    change: function(e,ui) 
    {
        //change the position of the fixed elements to the original one
        $sortable = $(this);
        $statics = $('.fixed', this).detach();
        $helper = $('<div class="portlet" style="background-color:#000"></div>').prependTo(this);
        $statics.each(function(){
            var $this = $(this);
            var target = $this.data('pos');
            $this.insertAfter($('.portlet', $sortable).eq(target));
        });
        $helper.remove();

        // animate all clones to the new position
        $("#content .portlet:not(.being-dragged, .ui-sortable-placeholder, .fixed)").each(function(){
            var item = $(this);
            var clone = item.data("clone");

            // stop current clone animations...
            clone.stop(true, false);

            var position = item.position(); // New position
            clone.animate({left: position.left, top:position.top}, 500);
        });

    },

    stop: function(e, ui){
        var el = $("#content .being-dragged");
        // Save the new position
        var newPosition = el.position();
        // Insert a placeholder for the final animation
        $('<div class="portlet ui-sortable-placeholder"></div>').insertBefore(el);
        el.css("left", lastPosition.left)
          .css("top", lastPosition.top)
          .css("position", "absolute")
          .animate({left: newPosition.left, top: newPosition.top}, 300, "swing", function() {
              // After the animation remove the placeholder and reset the element position
              $("#content .ui-sortable-placeholder").remove();
              $(this).css("left", "").css("top", "").css("position", "");
          })
          .removeClass("being-dragged");

        // Erase the temporary itens
        $("#cloned_items").empty();

        // make sure all our original items are visible again...
        $("#content .portlet").css("visibility", "visible");
    }

});

// Save the position of the element being dragged for the final animation
$(".portlet").on("mouseup", function() {
    lastPosition = $(this).position();
});

【讨论】:

  • 虽然这不是我想要的(动画是实时发生的,而不是事后发生的),但它比我最初的尝试要好得多,而且动画非常流畅。做得很好。
  • 在鼠标抬起后对所有面板进行动画处理并不好,它们必须回到原来的位置并动画到最后的位置。如果拖动时没有反馈,它会起作用,但我认为我这样做的方式更好。
  • 我认为您可能是对的,我喜欢您解决方案中的动画。不幸的是,我正在尝试模仿现有的功能。
  • 我不知道你到底想要什么,但你可以调整这段代码。例如,您可以将克隆动画到它们在stop 上的最终位置(遍历原始元素,保存/重置位置,动画)
猜你喜欢
  • 2013-02-18
  • 2014-07-29
  • 2011-04-20
  • 2015-12-24
  • 2011-07-15
  • 2011-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多