【问题标题】:Using jQuery to re-order and animate list items?使用 jQuery 重新排序和动画列表项?
【发布时间】:2011-12-28 17:46:25
【问题描述】:

所以,我有一个项目列表,类似于:

<ul id="listHolder">
    <li id="l1">List item 1</li>
    <li id="l2">List item 2</li>
    <li id="l3">List item 3</li>

等等。 定期触发 ajax 调用,我可能需要重新排序列表(通过使较低的项目之一成为列表中的第一个)。这很容易通过更改#listHolder 的HTML 来实现,但我想对其进行动画处理,以便适当的项目在页面上向上移动到正确的位置,而其他项目向下移动。

我不知道从哪里开始 =/

注意。它不必是一个列表:一个 div 或任何其他元素都可以。

【问题讨论】:

    标签: javascript jquery html jquery-animate html-lists


    【解决方案1】:

    好的,我做到了——比我想象的要简单。

    http://jsfiddle.net/Vyhph/

    请注意,如果您在一秒钟内单击多个列表对象,一切都会出错。你可以很容易地阻止它,但这对我来说不是问题。

    $("li").live("click", function() {
        var $myLi = $(this);
        var $myUl = $(this).parent();
        var listHeight = $myUl.innerHeight();
        var elemHeight = $myLi.height();
        var elemTop = $myLi.position().top;
        var moveUp = listHeight - (listHeight - elemTop);
        var moveDown = elemHeight;
        var liId = $myLi.attr("id");
        var enough = false;
        var liHtml = $myLi.outerHTML();
    
        $("li").each(function() {
            if ($(this).attr("id") == liId) {
                return false;
            }
            $(this).animate({
                "top": '+=' + moveDown
            }, 1000);
        });
    
        $myLi.animate({
            "top": '-=' + moveUp
        }, 1000, function() {
            $myLi.remove();
            var oldHtml = $myUl.html();
            $myUl.html(liHtml + oldHtml);
            $myUl.children("li").attr("style", "");
        });
    });
    
    (function($) {
        $.fn.outerHTML = function() {
            return $(this).clone().wrap('<div></div>').parent().html();
        }
    })(jQuery);
    

    【讨论】:

    • 太棒了,很高兴你有适合你的东西!对不起,我没有更多的时间来编写我的想法。旁注,将代码也放在 stackoverflow.com 上。这样,只要网站正常运行,您的答案就可用。 jsfiddle 可能随时更改其访问策略。
    【解决方案2】:

    就个人而言,我会抓住 jQuery UI 可排序功能并在 ajax 成功时触发事件。看看这个documentation,如果你喜欢这个主意,请告诉我。

    【讨论】:

    • 我对任何可行的方法都很满意。因此,将列表转换为 .sortable(),然后“手动”为对象设置动画,就像它一样?我试试看。
    • 去吧,看看我下面的答案。尽管我最终没有使它们可排序,但您仍然为我指明了正确的方向。干杯。
    • 有没有办法自动模拟列表项的重新排序,而不需要用户拖放?
    【解决方案3】:

    我不太喜欢克隆元素的想法,并且我正在尝试构建排行榜可视化,并不是真的想要更改 DOM,所以我使用数据属性和一些基本数学以不同的方式进行了操作。

    html:

            <ol id="leaderboard">
                <li class="leaderboarditem" data-key="A" data-rank="0"><span class="tag">A</span><span class="tagvalue">0</span></li>
                <li class="leaderboarditem" data-key="B" data-rank="1"><span class="tag">B</span><span class="tagvalue">0</span></li>
                <li class="leaderboarditem" data-key="C" data-rank="2"><span class="tag">C</span><span class="tagvalue">0</span></li>
            </ol>
    

    风格:

            .tag, .tagvalue { display: inline-block; }
            .tag { padding-left: 1em; width: 50%; font-weight: bold; background-color: rgb(235, 235, 235); }
            .tagvalue { border-left: 10px solid rgb(235, 235, 235); border-right: 10px solid rgb(235, 235, 235); border-top: 50px solid white; border-bottom: 50px solid white; padding-left: 1em;padding-right: 1em; }
            .leaderboarditem { display: block; width: 100%; font-size: 67pt; line-height: 119pt; font-weight: bold; position: relative; top: 0px; left: 0px; }
    

    (样式中的关键是位置:相对和显示:块)

    javascript:

    function (f, msg) {
        var leaderboard, key_count, key, value, tag, tag_value, list_item;
    
                    console.log(JSON.stringify(msg));
    
                    leaderboard = {
                        element : $('#leaderboard'),
                        data : []
                    };
    
                    key_count = 0;
                    for (key in msg) {
                        ++key_count;
                        value = msg[key];
    
                        list_item = $('.leaderboarditem[data-key=' + key.toUpperCase() + ']');
                        tag_value = list_item.find('.tagvalue').text(value);
    
                        leaderboard.data.push({ k: key.toUpperCase(), v: value, item: list_item });
                    }
    
                    leaderboard.data.sort(function (a, b) {
                        var a_value = a.v;
                        var b_value = b.v;
                        return b_value - a_value;
                    });
    
                    leaderboard.data.forEach(function(datum, rank) {
                        var old_rank, line_height, move_distance;
    
                        old_rank = datum.item.data('rank');
    
                        if (old_rank != rank) {
                            line_height = datum.item.height();
                            move_distance = (line_height * rank) - (line_height * old_rank);
    
                            datum.item.animate(
                                {'top' : '+=' + move_distance },
                                1e3,
                                function () {
                                    datum.item.data({ 'rank' : rank });
                                }
                            );
                        }
                    });
    
                }
            }
    

    【讨论】:

      猜你喜欢
      • 2013-09-02
      • 1970-01-01
      • 2015-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-16
      相关资源
      最近更新 更多