You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript和jQuery实现API数据更新时列表排序滑动动画

问题描述

我需要在从5个不同API获取数据时,实现按价格排序的滑动动画,动画效果类似联赛中低排名选手上升或游戏中的排序动画。以下是我在.cshtml中的代码:

<ul id="externalPharmacyList" @* data-aos="fade-up" *@></ul>


<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script>
$(document).ready(function () {
var data1 = @Html.Raw(Json.Serialize(Model));
var data2 = @Html.Raw(Json.Serialize(Model));
var jsonData = data1.concat(data2);

function displaySortedData() {
    // Modify the sorting function to compare copay values as numbers
    var sortedJsonData = jsonData.sort(function (a, b) {
        return parseFloat(a.copay) - parseFloat(b.copay);
    });

    for (var i = 0; i < sortedJsonData.length; i++) {
        var item = sortedJsonData[i];
        var fullAddress = item.address1 + " " + item.address2 + " " + item.city + " " + item.state + " " + item.zipCode;

        var listItemHtml = `
            <li style="display:none;">
                <div class="b-m-pharmacy-det">
                    <div class="b-p-name">
                        ${item.pharmacyName}
                        <small>${fullAddress}</small>
                    </div>
                    <div class="b-m-qty">
                        ${item.quantity} ${item.drugName}
                    </div>
                    <div class="b-m-price" style="text-align:right">
                        ${item.copay}
                    </div>
                </div>
            </li>`;

        $('#externalPharmacyList').append(listItemHtml);
    }

    // Apply the slide animation to the list items
    $('#externalPharmacyList li').slideDown();
   }

// Call the displaySortedData function after both data sets are concatenated
  displaySortedData();
 });
</script>

当前代码逻辑:将SOAP API返回的Model序列化为JSON,拼接多组数据后按copay字段排序,生成隐藏的<li>元素后统一调用slideDown动画。但我希望在排序过程中呈现动画,而非排序完成后统一显示,请问我哪里出错了,该如何调整?


解决方案

问题根源

当前代码是先一次性完成排序并插入所有元素到DOM,再统一触发显示动画,本质上只是静态展示最终排序结果,没有模拟排序过程中元素位置交换的动态效果,所以看不到“排序时的动画”。

调整步骤

  1. 先渲染所有未排序元素到DOM
    跳过提前排序的步骤,先把所有数据对应的<li>元素插入列表(设置绝对定位方便后续移动动画),让用户先看到初始的未排序状态。

  2. 模拟排序过程+逐帧动画
    不要用原生sort直接生成最终结果,改用冒泡排序这类步骤直观的算法,每完成一次元素位置交换,就用jQuery的animate方法展示元素移动的动画效果,让排序过程可视化。

  3. 修改后的完整代码

<ul id="externalPharmacyList" style="position: relative; list-style: none; padding: 0; margin: 0;"></ul>

<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script>
$(document).ready(function () {
    // 替换为你的真实多API数据拼接逻辑
    var data1 = @Html.Raw(Json.Serialize(Model));
    var data2 = @Html.Raw(Json.Serialize(Model));
    var jsonData = data1.concat(data2);

    // 渲染未排序的初始列表项
    function renderUnsortedItems() {
        var list = $('#externalPharmacyList');
        list.empty();
        var itemHeight = 60; // 每项固定高度,需和动画top值对应
        jsonData.forEach(function(item, index) {
            var fullAddress = item.address1 + " " + item.address2 + " " + item.city + " " + item.state + " " + item.zipCode;
            var listItemHtml = `
                <li style="display:block; position: absolute; top: ${index * itemHeight}px; left: 0; width: 100%; margin: 0; padding: 10px; box-sizing: border-box; background: #fff; border-bottom: 1px solid #eee;">
                    <div class="b-m-pharmacy-det">
                        <div class="b-p-name">
                            ${item.pharmacyName}
                            <small>${fullAddress}</small>
                        </div>
                        <div class="b-m-qty">
                            ${item.quantity} ${item.drugName}
                        </div>
                        <div class="b-m-price" style="text-align:right">
                            ${item.copay}
                        </div>
                    </div>
                </li>`;
            list.append(listItemHtml);
        });
    }

    // 冒泡排序+位置交换动画
    function animateSorting() {
        var items = $('#externalPharmacyList li');
        var itemsArray = Array.from(items);
        var swapped;
        var index = 0;
        var itemHeight = 60;

        function bubbleStep() {
            swapped = false;
            for (var i = 0; i < itemsArray.length - 1 - index; i++) {
                var currentCopay = parseFloat(itemsArray[i].querySelector('.b-m-price').textContent.trim());
                var nextCopay = parseFloat(itemsArray[i+1].querySelector('.b-m-price').textContent.trim());
                
                if (currentCopay > nextCopay) {
                    // 交换数组中的元素引用
                    [itemsArray[i], itemsArray[i+1]] = [itemsArray[i+1], itemsArray[i]];
                    // 动画移动元素到目标位置
                    $(itemsArray[i]).animate({top: i * itemHeight}, 300);
                    $(itemsArray[i+1]).animate({top: (i+1) * itemHeight}, 300);
                    swapped = true;
                }
            }
            index++;
            // 等待当前轮动画完成后执行下一轮
            if (swapped && index < itemsArray.length) {
                setTimeout(bubbleStep, 350);
            } else {
                // 排序完成后恢复相对定位,避免布局异常
                items.css({position: 'relative', top: 'auto'});
            }
        }

        bubbleStep();
    }

    // 执行流程:先渲染初始列表,延迟启动排序动画
    renderUnsortedItems();
    setTimeout(animateSorting, 500);
});
</script>

关键说明

  • 定位逻辑:用绝对定位实现元素上下移动的平滑动画,排序完成后改回相对定位,保证后续页面布局正常。
  • 排序算法选择:冒泡排序的交换步骤直观,适合做逐帧动画;如果数据量较大,可替换为插入排序,动画逻辑保持一致。
  • 异步API处理:如果是从5个异步API获取数据,需用Promise.all等待所有请求完成后,再调用renderUnsortedItems,避免数据不全导致的错误。

内容的提问来源于stack exchange,提问作者Sandeep Verma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:25:23