【问题标题】:How to set the index for a dynamically changing table?如何为动态变化的表设置索引?
【发布时间】:2018-06-18 02:10:54
【问题描述】:

我创建了一个表单,您可以在其中使用 javascript 和 jQuery 添加或删除表行。我想知道如何获取和设置每个表行的索引,以便即使我要从表中间删除和元素,也可以保持顺序。该表的格式为:

<thead>
    <tr>
        <th>Index</th>
        <th>Name</th>
        <th>Property</th>
        <th>Edit/Delete</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td class="index">Index goes here (1)</td>
        <td>NameOne</td>
        <td>PropOne</td>
        <td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
    </tr>
    <tr>
        <td class="index">2</td>
        <td>NameTwo</td>
        <td>PropTwo</td>
        <td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
    </tr>
    <tr>
        <td class="index">3</td>
        <td>NameThree</td>
        <td>PropThree</td>
        <td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
    </tr>
</tbody>

现在我想要实现的是,如果我要删除第二行,前第三行的索引应该自动更改为 2,如果我要添加新元素,它应该自动采用索引值 3 等等开。

我试图通过以下方式实现:

function setIndex(){
   $("td.index").each(function(index) {
       $(this).text(++index);
   });
}

但是当我使用上述函数时,虽然添加元素时的初始索引正确打印,但当我在删除或编辑行后再次调用该函数时索引不会正确更新(我使用 jQuery remove 删除了该行)。

我也在用 jQuery append() 创建新的表行。

我认为虽然我使用了 remove(),但它们并没有像我在 setIndex() 中使用 console.log("test") 语句时那样被完全删除,尽管“test”应该只打印两次(我最初创建了 3 行并删除了其中一个)它打印了三次,表示有 3 个 tr.index。

请帮我解决同样的问题。

【问题讨论】:

标签: javascript jquery css html-table


【解决方案1】:

编辑

Praven Prajapati的回答让我吃惊。
我不知道这么酷的 CSS 功能。

Praven 的回答真的更好

如果您需要在 JS/jQuery 代码中引用该数字...并且无法获取它,因为它不是 DOM 伪元素...然后使用 .index() 来表示您的特定部分代码!让 CSS 处理其余部分。




jQuery方式:

您需要引用行索引...使用.index() 方法。

然后在.delete点击(我相信你可以删除行),只需调用一个函数来使用该方法更新行索引单元格。

添加新行后相同...

重要
在表行中存在的类上使用delegation.on(),因为您添加了页面加载代码解析中不存在的新行。 ;)

这是Will 的陷阱。 (见his answer

function updateRowCount(){
  $("table tbody tr").each(function(){
    $(this).find(".index").html($(this).index());
  });
}

// Run on load
updateRowCount();

$(document).on("click",".delete",function(){  // Use delegation here!
  $(this).parents("tr").remove();
  updateRowCount();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<table>
  <thead>
      <tr>
          <th>Index</th>
          <th>Name</th>
          <th>Property</th>
          <th>Edit/Delete</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td class="index"></td>
          <td>NameOne</td>
          <td>PropOne</td>
          <td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
      </tr>
      <tr>
          <td class="index"></td>
          <td>NameTwo</td>
          <td>PropTwo</td>
          <td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
      </tr>
      <tr>
          <td class="index"></td>
          <td>NameThree</td>
          <td>PropThree</td>
          <td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
      </tr>
  </tbody>
</table>

【讨论】:

    【解决方案2】:

    您可以使用 CSS counter-resetcontent 属性。

    counter-reset 属性允许对元素进行自动编号
    它适用于任何元素。

    counter-reset 属性用于将 CSS 计数器重置为给定值。 它将命名计数器设置为特定值。

    body{
      counter-reset: Serial;           /* Set the Serial counter to 0 */
    }
    
    table{
      border-collapse: collapse;
    }
    
    tr td:first-child:before{
      counter-increment: Serial;      /* Increment the Serial counter */
      content:counter(Serial);        /* Display the counter */
    }
    <table border="1">
      <thead>
        <tr>
          <th>Automatic Serial number</th>
          <th>Column 1</th>
          <th>Column 2</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td></td>
          <td>Column 1</td>
          <td>Column 2</td>
        </tr>
        <tr>
          <td></td>
          <td>Column 1</td>
          <td>Column 2</td>
        </tr>
        <tr>
          <td></td>
          <td>Column 1</td>
          <td>Column 2</td>
        </tr>
        <tr>
          <td></td>
          <td>Column 1</td>
          <td>Column 2</td>
        </tr>
        <tr>
          <td></td>
          <td>Column 1</td>
          <td>Column 2</td>
        </tr>
        <tr>
          <td></td>
          <td>Column 1</td>
          <td>Column 2</td>
        </tr>
        <tr>
          <td></td>
          <td>Column 1</td>
          <td>Column 2</td>
        </tr>
        <tr>
          <td></td>
          <td>Column 1</td>
          <td>Column 2</td>
        </tr>
      </tbody>
    </table>

    【讨论】:

    • 需要解释......但是是的。有趣的 CSS 方式。不要只是像这样转储代码。解释是人们使用 StackOverflow 的主要原因。
    • 我将您的答案标记为“质量非常低”...而且,如果您不进行一些解释进行编辑,它很可能会被从审核中删除。欢迎来到 SO! -- 那会很伤心,因为你的答案比我的好。
    • 好的...您已编辑。你的答案真的比我的好而且你是新手……所以我会帮你一点。如果您同意(如果您在评论中回答我是),我将非常轻微地编辑您的答案。请不要提及 W3schools,因为该网站大部分时间都已过时(或完全错误)。
    • ;) @Will。这就是我如此喜欢的原因。
    【解决方案3】:

    我建议使用@pravin-prajapati 的 CSS/Counter 答案,因为它不需要 JS 开销并且可以轻松扩展。

    对您的代码有什么问题很感兴趣,因为它在我看来很好,所以重新构建了它。似乎工作正常。

    我猜问题实际上在于您将代码附加到 .delete 点击的方式,尤其是如果您在编辑后添加新行或重新创建行。 p>

    如果在初始document.ready(或window.onload...)将回调附加到现有.delete 元素后添加新行,它不会自动将回调附加到新.delete 元素。

    换句话说,不要在你的 init 中这样做:

    $('.delete').on('click', function(){
      // do stuff
    });
    

    因为这仅适用于初始化期间存在的.delete 元素。有几种方法可以解决这个问题,但一种简单的方法是在行的父级上侦听单击事件,然后在运行回调之前将它们过滤到您的实际目标。 jQuery's on method 让这一切变得简单。

    下面是一个以表作为事件监听器的示例。

    编辑
    如果由于某种原因无法做到这一点,您可能会考虑使用jQuery.clone() 并将withDataAndEvents 和/或deepWithDataAndEvents 设置为true,如$('tr.template').clone(true, true);。这将复制&lt;tr&gt; 和附加到它的任何事件处理程序(第一个'true')附加到它的任何子元素的任何事件处理程序(第二个'true')。 jQuery Clone Docs

    $(document).ready(function(){
    
      // your function, copied 100%
      function setIndex(){
       $("td.index").each(function(index) {
           $(this).text(++index);
       });
      }
    
      // set the index to begin with. Note the last three 
      // row indexes are actually empty in the sample HTML
      setIndex();
    
      // Move the click listener to the table. 
      $('table').on('click', '.delete', function(){    
        // remove the tr...
        $(this).parents('tr').remove();
        //... and reset the index
        setIndex();  
      })
      
    });
    table {
      font-family: sans-serif;
      margin: 10px;
    }
    table td {
      border: 1px solid #ccc;
      padding: 10px;
    }
    .delete {
      color: red;
      cursor: pointer;
      font-size: 80%;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <table>
      <thead>
        <tr>
            <th>Index</th>
            <th>Name</th>
            <th>Property</th>
            <th>Edit/Delete</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="index">Index here</td>
            <td>NameOne</td>
            <td>PropOne</td>
            <td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
        </tr>
        <tr>
            <td class="index">2</td>
            <td>NameTwo</td>
            <td>PropTwo</td>
            <td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
        </tr>
        <tr>
            <td class="index">3</td>
            <td>NameThree</td>
            <td>PropThree</td>
            <td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
        </tr>
          <tr>
            <td class="index"></td>
            <td>Name 4</td>
            <td>Prop 4</td>
            <td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
        </tr>
          <tr>
            <td class="index"></td>
            <td>Name 5</td>
            <td>Prop 5</td>
            <td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
        </tr>
          <tr>
            <td class="index"></td>
            <td>Name 6</td>
            <td>Prop 6</td>
            <td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
        </tr>
    </tbody>
    </table>

    【讨论】:

    • 嘿... lollll!太棒了true!我对这种情况感到惊讶。不错的收获。
    • @LouysPatriceBessette :)。对他遇到的实际问题进行了新的编辑。估计是事件委托。
    • 何曼……这被深深地隐藏了。我怎么没想到?!!我投票了 x 个问题来结束,因为它是 that 的重复! --- 我确定你终于找到了 OP 的问题。我不能多次投票。 ;)
    • 有趣的是我假设了它的删除功能......并犯了完全相同的错误,因为我不关心附加......我会再次编辑哈哈!
    猜你喜欢
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 2020-04-17
    • 1970-01-01
    • 2017-05-31
    相关资源
    最近更新 更多