将多个列表折叠为一个动画

时间:2014-12-19 14:39:24

标签: jquery list jquery-animate transition collapse

我在一个页面上有多个列表。可能存在的列表数量是任意的,但可能限制为10个。

此页面有两种观点:

  • 模式1:所有项目都已分类并列在不同的通道中。
  • 模式2 :所有项目都折叠为一个列表。

用户应该能够在两种模式之间切换。我有[大致]工作 - 它们被折叠成一个列表,但是它们从父/源列表中丢失了样式。

理想情况下,我喜欢这两种动画模式之间的过渡;也就是说,当用户单击模式切换按钮时,来自每个通道的所有列表项都会动画/折叠为单个按字母顺序排列的列表。进入模式2 (单一列表模式)后,再次单击切换按钮可以将列表项动画回原始列表。

Here's a Fiddle I've been working on.

在我的代码中,我有四个列表,其中包含项目可以折叠的隐藏<ul>。我无法弄清楚动画的方式和位置。

$(function() {
    $("button").on("click", function() {
        if($(this).text() == "Mode 1") {
            $("#list").show();
            $("li").remove().clone().appendTo("#list");
            $("ul:not(#list)").hide();
            $("button").text("Mode 2");
        }
    });
});

<button>Mode 1</button>

// The hidden list
<ul id="list"></ul>

<ul id="red">
    <li>A</li>
    ...
</ul>
<ul id="blue">
    <li>K</li>
    ...
</ul>
<ul id="gray">
    <li>U</li>
    ...
</ul>
<ul id="green">
    <li>AA</li>
    ...
</ul>

编辑:我想我应该指定我想要的动画。我希望每个单独的列表项目能够飞到&#34;飞行&#34;从它的原始位置到单个折叠列表。

1 个答案:

答案 0 :(得分:1)

好的Jon,对于每件从其当前位置动画到新位置的动画,你得到每个元素的偏移量,让它们position:absolute;然后将它们设置为正确的位置。

In-progress fiddle here

这是伴随它的jQuery。这也使您的HTML布局保持不变:

$(function() {
$("button").on("click", function() {
    if($(this).text() == "Mode 1") {
        var elem = $('ul:not(#list) > li'),
            elemH = elem.first().outerHeight(),
            list1Last = {x:$('#red > li:last-of-type').offset().left,
                         y:$('#red > li:last-of-type').offset().top},
            oElem = {x:0, y:0, w:0, h:0}
        $('ul:not(#red)').each(function(e){
            $(this).find('li').each(function(i){
                oElem = {x:$(this).offset().left,
                         y:$(this).offset().top,
                         w:$('#red').width(),
                         h:$(this).outerHeight()}
                console.log(oElem.x, oElem.y);
                $(this).css({"position":"absolute", 
                             "top":oElem.y+(oElem.h*i)+"px",
                             "left":oElem.x+"px",
                             "width":oElem.w+"px"});
                $(this).delay(200*i).animate({"top":(list1Last.y+elemH)*e+(i*elemH)+"px",
                                              "left":list1Last.x+"px"}, 200);
            });
        })
    } else {

    }
});
});

这样做是使用offset()获取每个元素的当前位置,然后我更改CSS以使其position:absolute;并为其提供lefttop值。这无缝地使它们绝对定位而没有任何碰撞。然后,我立刻将它们设置为新的位置,就像它们正如你所说的那样飞行。有办法让它们一个接一个地飞行,但这需要更多的编辑。