【问题标题】:html table rows slideshowhtml表格行幻灯片
【发布时间】:2020-04-13 23:00:46
【问题描述】:

在一个页面中,我正在填充一个 HTML 表,其中可能有从 1 到 100 的随机行数。无论行数如何,我只需要在一个视图中显示该表的 10 行,然后再显示下 10 个幻灯片5秒。

示例表结构

<table>
  <thead>
    <th>Competition</th>
    <th>Adam</th>
  </thead>
  <tbody id='tableslide'>
  <tr>
    <td>Swimming</td>
    <td>1</td>
  </tr>
  <tr>
    <td>Running</td>
    <td>2</td>
  </tr>
  <tr>
    <td>Shooting</td>
    <td>3</td>
  </tr>
  <tr>
    <td>Shooting</td>
    <td>4</td>
  </tr>
  <tr>
    <td>sample</td>
    <td>5</td>
  </tr>
  <tr>
    <td>test</td>
    <td>6</td>
  </tr>
  <tr>
    <td>Shooting</td>
    <td>7</td>
  </tr>
  <tr>
    <td>Shooting</td>
    <td>8</td>
  </tr>
  <tr>
    <td>goto</td>
    <td>9</td>
  </tr>
  <tr>
    <td>mean</td>
    <td>10</td>
  </tr>
  <tr>
    <td>acomon</td>
    <td>11</td>
  </tr>
  <tr>
    <td>server</td>
    <td>12</td>
  </tr>

   <tr>
    <td>Shooting</td>
    <td>13</td>
  </tr>
  <tr>
    <td>Shooting</td>
    <td>14</td>
  </tr>
  <tr>
    <td>sample</td>
    <td>15</td>
  </tr>
  <tr>
    <td>test</td>
    <td>16</td>
  </tr>
  <tr>
    <td>Shooting</td>
    <td>17</td>
  </tr>
  <tr>
    <td>Shooting</td>
    <td>18</td>
  </tr>
  <tr>
    <td>goto</td>
    <td>19</td>
  </tr>
  <tr>
    <td>goto</td>
    <td>20</td>
  </tr>
  <tr>
    <td>goto</td>
    <td>21</td>
  </tr>
   <tr>
    <td>goto</td>
    <td>22</td>
  </tr>
   <tr>
    <td>goto</td>
    <td>23</td>
  </tr>
  </tbody>
</table>

我尝试了一个示例代码,该示例代码显示了前 10 条记录,但随后它显示了剩余的全部记录。我想将总行数减 10 并在每张幻灯片中显示。

$(function () {
    var selectors = [
        ":lt(10)",
        ":gt(9)"
    ];
    var $tableslide = $("#tableslide").children(selectors[1]).hide().end();
    var state = false;
    setInterval(function () {
        var s = state;
        $tableslide.children(selectors[+s]).fadeOut().promise().then(function () {
            $tableslide.children(selectors[+!s]).fadeIn();
        });
        state = !state;
    }, 3000);
});

【问题讨论】:

    标签: javascript jquery html-table


    【解决方案1】:

    正如@antanta 的回答中提到的 - 有很多方法可以实现这一点,这是我的解决方案(使用 showhide 而不是淡入淡出):

    $('table tr:gt(10)').hide();
    
    setInterval(function() {
    
    var last = $('table tr:visible:last')
    $('table tr').hide();
    (last.next().length ? last.nextAll(':lt(10)', ':not(:visible)') : last.siblings(':lt(10)')).show();
    }, 5000);
    

    解释:

    隐藏除前 10 列以外的所有列,然后每 5 秒获取最后一个可见的 tr 元素并显示其下 10 个兄弟元素,如果它没有下一个兄弟元素,则显示前 10 个兄弟元素。

    $('table tr:gt(10)').hide();
    
    setInterval(function() {
    
    var last = $('table tr:visible:last')
    $('table tr').hide();
    (last.next().length ? last.nextAll(':lt(10)', ':not(:visible)') : last.siblings(':lt(10)')).show();
    }, 3000);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <table>
      <thead>
        <th>Competition</th>
        <th>Adam</th>
      </thead>
      <tbody id='tableslide'>
      <tr>
        <td>Swimming</td>
        <td>1</td>
      </tr>
      <tr>
        <td>Running</td>
        <td>2</td>
      </tr>
      <tr>
        <td>Shooting</td>
        <td>3</td>
      </tr>
      <tr>
        <td>Shooting</td>
        <td>4</td>
      </tr>
      <tr>
        <td>sample</td>
        <td>5</td>
      </tr>
      <tr>
        <td>test</td>
        <td>6</td>
      </tr>
      <tr>
        <td>Shooting</td>
        <td>7</td>
      </tr>
      <tr>
        <td>Shooting</td>
        <td>8</td>
      </tr>
      <tr>
        <td>goto</td>
        <td>9</td>
      </tr>
      <tr>
        <td>mean</td>
        <td>10</td>
      </tr>
      <tr>
        <td>acomon</td>
        <td>11</td>
      </tr>
      <tr>
        <td>server</td>
        <td>12</td>
      </tr>
    
       <tr>
        <td>Shooting</td>
        <td>13</td>
      </tr>
      <tr>
        <td>Shooting</td>
        <td>14</td>
      </tr>
      <tr>
        <td>sample</td>
        <td>15</td>
      </tr>
      <tr>
        <td>test</td>
        <td>16</td>
      </tr>
      <tr>
        <td>Shooting</td>
        <td>17</td>
      </tr>
      <tr>
        <td>Shooting</td>
        <td>18</td>
      </tr>
      <tr>
        <td>goto</td>
        <td>19</td>
      </tr>
      <tr>
        <td>goto</td>
        <td>20</td>
      </tr>
      <tr>
        <td>goto</td>
        <td>21</td>
      </tr>
       <tr>
        <td>goto</td>
        <td>22</td>
      </tr>
       <tr>
        <td>goto</td>
        <td>23</td>
      </tr>
      </tbody>
    </table>

    【讨论】:

    • 这里的一个问题是未修复。它在第一张幻灯片后消失
    • $('#tableslide tr:gt(10)').hide(); setInterval(function() { var last = $('#tableslide tr:visible:last') $('#tableslide tr').hide(); (last.next().length ? last.nextAll(':lt (10)', ':not(:visible)') : last.siblings(':lt(10)')).show(); }, 3000);
    • 这解决了这个问题。谢谢
    • 我面临的另一个问题是这个 html 表是在 ajax 调用中动态填充的。我做了一个 fn 并将我们的代码放入其中并调用。当我成功调用我们的 ajax 代码时,我没有得到正确的结果。事情变得一团糟..
    【解决方案2】:

    有很多方法可以实现这一目标。你的选择器有些不对劲,IMO 你做的太复杂了,难以理解。这是一个工作代码:

    $(function () {
        var $children = $("#tableslide").children();
        var step = 10, total = $children.length, currentStart = 0;
    
        // hide all
        $children.hide();
    
        // buffer to know what was shown, you could also go with :visible
        var $lastVisibleItems = $children.slice(currentStart, currentStart + step).show();
    
        setInterval(function () {
                 $lastVisibleItems.fadeOut().promise().then(function () {
                currentStart += step;
                $lastVisibleItems = $children.slice(currentStart, currentStart + step).fadeIn();
              if (currentStart + step >= $children.length) {
                // reset to beginning, actually -step because it will because 0 after +step
                currentStart = -step;
              }
          });
        }, 3000);
    });
    

    Working Fiddle

    说明:

    1. 首先缓冲所有子元素
    2. 设置您的步骤,即一次可见的项目。
    3. 设置您当前的开始,即在任何时候项目 [currentStart, currentStary + step) 都是可见的。您使用 slice 来获取子数组
    4. 在间隔调用中,只需隐藏最后可见的项目(您已经在缓冲区变量中拥有它们,无需遍历 DOM)。使用步骤增加当前开始,显示新项目,并再次缓冲它们。
    5. 如果您的结束索引(当前开始 + 步长)等于或大于所有子项计数,则重置为零(如果您想停止动画,则清除间隔)

    更新:

    由于问题现在包括通过 ajax 动态填充表格,因此这里是新代码:

    $(function () {
        var interval;
        var $table = $("#tableslide"), $children = $table.children();
        var step = 10, total = $children.length, currentStart = 0;
    
        function startInterval() {
          return setInterval(function () {
                currentStart += step;
              if (currentStart + step > $children.length) {
                    // you have reached the end and you will not render a whole page so clear here
                    clearInterval(interval); 
                    interval = null;
                  } else {
                    $lastVisibleItems.fadeOut().promise().then(function () {
                            $lastVisibleItems = $children.slice(currentStart, currentStart + step).fadeIn();
                        });
                  }
    
            }, 3000);
        }
    
        function restoreInterval() {
                if (!interval) {
                // you have stopped your timer, hence start it again, without changing the currentStart
                interval = startInterval();
              } else {
                // do nothing
              }
        }
    
        // hide all
        $children.hide();
    
        // buffer to know what was shown, you could also go with :visible
        var $lastVisibleItems = $children.slice(currentStart, currentStart + step).show();
    
        interval = startInterval();
    
        $.ajax({
            url: '/testurl',
            type: 'POST',
            //complete: function(result) { //use for testing
            success: function(result) {
                    // modify your DOM with the server response. in my case add 10 dummy rows
                for (var i = 1; i <= 10; i++) {
                    $table.append($("<tr><td>Ajax row " + i + "</td><td>" + i + "</td></tr>").hide());
                }
                // add rows to table and do not forget to modify the varuiable $children
                $children = $("#tableslide").children();
    
                // Restore the interval
                restoreInterval();
            }
        })
    });
    

    附:现在这是一个更复杂的代码,我认为您会更加困惑,但我希望它会有所帮助。将success 替换为complete 所以你可以测试它。 无论您进行多少次 ajax 调用,它都会起作用,如果您检测到接近结尾的 1 或 2 页,您甚至可以从间隔函数进行 ajax 调用。

    【讨论】:

    • 我可以从 ajax 成功调用它吗
    • 如果表格是用 ajax 动态填充的,你必须检查 5. 步骤是否已经到达结束索引。如果是,则清除间隔,然后在 ajaxSuccess 上再次启动间隔,前提是您已经停止了间隔(因此请跟踪间隔是否处于活动状态)。之所以需要此同步,是因为您不知道哪个会更快 -> setInterval 将结束或 ajax 调用以获取新行。更新:您也可能希望在结束前停止 1 步,这样您就不会显示非完整页面。
    猜你喜欢
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2015-04-21
    相关资源
    最近更新 更多