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

jQuery加载表格行时按钮禁用及Loading显示异常问题求助

问题分析与解决方案

问题根源

初始代码的核心问题

你的初始代码里,禁用按钮、显示Loading后,同步执行了启用按钮和隐藏Loading的代码。浏览器的UI更新是在JavaScript执行线程空闲时才会触发,所以这一系列操作瞬间完成,用户根本看不到Loading状态和按钮禁用的变化。

最小复现示例的问题

  1. 完全缺失按钮禁用/启用的逻辑
  2. slideDown的回调函数会在每一行动画完成时都触发一次,导致Loading文本提前被隐藏,而非所有行加载完成后才隐藏

修正后的代码实现

1. 基础功能修正(对应初始代码)

如果表格行加载是异步操作(比如AJAX请求),必须把启用按钮和隐藏Loading的逻辑放在异步操作的回调里:

HTML(无需修改)

<div class="load-more-container">
<button id="btn-load-more">Load More</button>
</div>
<p id="loading" style="display:none"> Loading ... </p>

JavaScript

$("#btn-load-more").on("click", function (event) {
  event.preventDefault();
  const $btn = $(this);
  // 立即禁用按钮并显示Loading
  $btn.prop("disabled", true);
  $("#loading").show();

  // 模拟异步加载(实际开发中替换为AJAX请求)
  setTimeout(() => {
    // 这里写加载表格行的逻辑
    console.log("表格行加载完成");

    // 加载完成后恢复按钮状态并隐藏Loading
    $btn.prop("disabled", false);
    $("#loading").hide();
  }, 1000);
});

2. 最小复现示例的完整修正

针对表格行展开场景,需要确保:

  • 点击时立即禁用按钮
  • 所有行的动画完成后,再恢复按钮状态并隐藏Loading

HTML(修正tbody的ID,与JS选择器对应)

<script src="https://code.jquery.com/jquery-3.6.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>

<div>
<table id="my-table">
<thead>
<tr>
    <th>Company</th>
    <th>Contact</th>
    <th>Country</th>
</tr>
</thead>
<!-- 给tbody添加ID,匹配JS选择器 -->
<tbody id="my-table-tbody">
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
</tbody>
</table>

<button id="btn-load-more" style="cursor: pointer">Load More</button>
    
<p id="loading" style="text-align:center; display:none"> Loading ... </p>
</div>

JavaScript

$(document).ready(function (){
  const $tbody = $("#my-table-tbody");
  const $loadBtn = $("#btn-load-more");
  const $loading = $("#loading");

  // 初始化隐藏超出前2行的内容
  $tbody.find("tr").slice(2).hide();
  // 初始检查是否有隐藏行,没有则隐藏按钮
  if ($tbody.find("tr:hidden").length === 0) {
    $loadBtn.hide();
  }

  $loadBtn.on("click", function (event) {
    event.preventDefault();
    // 立即禁用按钮并显示Loading
    $loadBtn.prop("disabled", true);
    $loading.show();

    const $rowsToShow = $tbody.find("tr:hidden").slice(0,2);
    // 使用promise()确保所有动画完成后再执行回调
    $rowsToShow.slideDown("fast").promise().done(function(){
      // 所有动画完成后恢复状态
      $loadBtn.prop("disabled", false);
      $loading.hide();
      // 检查是否还有隐藏行,没有则隐藏按钮
      if ($tbody.find("tr:hidden").length === 0) {
        $loadBtn.hide();
      }
    });
  })
});

关键注意点

  • UI更新时机:浏览器会在当前JavaScript任务执行完毕后才更新UI,所以必须把状态恢复逻辑放在异步操作(AJAX、动画)的回调里。
  • jQuery动画回调:slideDown的普通回调会为每个匹配元素触发一次,使用.promise().done()可以确保所有动画完成后只执行一次回调。
  • 按钮状态管理:始终在操作开始时禁用按钮,避免用户重复点击;操作完成后再恢复,同时处理无更多内容时隐藏按钮的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 17:55:18