jQuery-UI sortable:在帮助程序删除后从原始位置动画到新位置

时间:2014-01-31 10:59:57

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

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时,将从旧位置动画到新位置。应保持分拣过程中的当前运动以给最终用户反馈,但最终动画应在助手掉落后进行。

有没有人有任何关于如何实现这一目标的想法或例子?

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

提前致谢。

编辑

你可以在这里看到:http://jsfiddle.net/BWNE2/2/当固定的portlet位于位置3(顶部的右上角)时动画效果更加不足。排序时通常不在正确的位置,但它确实会在排序结束时恢复到正确的位置。

1 个答案:

答案 0 :(得分:4)

根据找到的解决方案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();
});