使用jQuery/JavaScript操作HTML表(用于列重新排序、可见性)

Manipulate an HTML table (for column reordering, visibility) using jQuery/JavaScript?

本文关键字:新排序 排序 可见性 用于 jQuery JavaScript 操作 HTML 使用      更新时间:2023-09-26

我有一个ASP.NET MVC站点,视图中有一个HTML表。根据示例html代码,我有时会在单元格中嵌套表,但在问题结束之前,这一点可以忽略。

<table id="mainTable">
      <thead>
      <tr>
        <th>Col 1</th>
        <th>Col 2</th>
        <th>Col 3</th>
      </tr>
      </thead>
      <tbody>
      <tr>
          <td>data</td>
          <td>data</td>
          <td>data</td>
      </tr>
      <tr>
          <td>data</td>
          <td>
               <table class="nestedTable">
                   <tr><th>Col 1</th><th>Col 3</th></tr>
                   <tr>
                       <td>nested data</td><td>nested data 1</td>
                    </tr>
               </table>
          </td>
          <td>data</td>
      </tr>
    </tbody>
</table>

我现在想使用这个jQuery多选插件,允许用户选择他们想要的列的顺序,以及显示/隐藏某些列。所以我正在创建一个看起来像这样的多选:

<select id="cols" class="multiselect" multiple="multiple" name="cols[]">
    <option value="Col1">Col1</option>
    <option value="Col2">Col2</option>
    <option value="Col3">Col3</option>
</select>

以允许用户选择订单,然后我将暂时将这些数据存储在本地存储中。因此,我存储的只是一个字符串数组,它表示用于设置多选选择器的"列的可见顺序"。这样做效果很好,我能够持久化这个数组或"有序列名"。

我的问题是,使用这个字符串数组并更新HTML表以反映列顺序和列可见性的最佳方法是什么?

我知道有更大的html表网格框架具有此功能,但在这种情况下,我需要坚持使用手工编码的html表。

更新:

@里克·希区柯克(Rick Hitchcock(在下面的回答让我百分之九十都明白了,但有一个悬而未决的问题让我的问题有点复杂。在某些情况下,我在主表中有一个嵌套表。我已经更新了这个问题,将这种情况包括在内我不希望列选择器代码影响嵌套表,所以我正在寻找一种只让代码影响主表的方法。

[根据更新的问题删除原始答案]

给定这样的数组(arr(:

['Col 2', 'Col 3', 'Col 1']

…或者这个:

['Col 1', 'Col 3']

…这将使主表的列匹配,并隐藏未使用的列:

var tr= $('#mainTable > tbody > tr, #mainTable > thead > tr');
$('> th, > td', tr).hide();
$.each(arr, function(_, val) {
  var col=  $('> th', tr)
              .filter(function() {
                return $(this).text()===val;
              })
              .index();
  $(tr).append(function() {
    return $('> td, > th', this).eq(col).show();
  });
});

Fiddle

单击按钮可重新排序表格。


它的工作原理

这将限制后续选择器到主表的行:

var tr= $('#mainTable > tbody > tr, #mainTable > thead > tr');

即使您排除了tbody,它也会为您添加。因此,这始终是一个空集合:$('#mainTable > tr')


这只隐藏tr集合的直接子级(来自上一行(:

$('> th, > td', tr).hide();

作为副作用,所有子体也将被隐藏。

它相当于:

$(tr).children('th, td').hide();

jQuery的childrenfind方法通常是不必要的(而且成本高昂(,因为您可以使用CSS选择器来完成同样的事情–特别是考虑到可选context参数的优点:

$( selector [, context ] )

这会查看数组的每个元素:

$.each(arr, function(_, val) {
  ...
});


这将获得th元素(即tr集合的直接子元素(的index(),其中其text()与数组值匹配:

var col=  $('> th', tr)
              .filter(function() {
                return $(this).text()===val;
              })
              .index();

这就是我们要展示的专栏。


最后,这会将其所有具有该列编号的子项附加到tr集合的每个成员,并显示它们:

$(tr).append(function() {
  return $('> td, > th', this).eq(col).show();
});

jQuery的append()方法(类似于JavaScript的appendChild()方法(移动元素–进入DOM或DOM中的其他位置。

知道了这一点,我们通常可以避免使用detach()之类的方法。