基于data-group属性实现带标题的表格数据过滤

碧海醫心
发布: 2025-11-30 12:00:08
原创
313人浏览过

基于data-group属性实现带标题的表格数据过滤

本教程详细介绍了如何使用jQuery和HTML的`data-group`属性,实现对包含多个`thead`部分的复杂表格进行高效的数据过滤。通过将`thead`和其对应的`tbody`逻辑分组,我们能够确保在搜索时,不仅显示匹配的行,还能同时显示其所属的标题部分,从而提升用户体验和数据可读性。

在现代Web应用中,展示大量数据通常会采用表格形式。当表格数据量庞大且结构复杂,例如包含多个逻辑分区,每个分区都有自己的标题(<thead>)时,实现一个用户友好的搜索过滤功能就显得尤为重要。传统的表格过滤方法往往只关注<tbody>中的行(<tr>),而忽略了与这些行相关联的<thead>部分的可见性,这可能导致用户在过滤后失去上下文信息。

挑战:多thead表格的过滤问题

假设我们有一个大型表格,其中包含多个独立的部门信息,每个部门都由一个<thead>作为标题,紧随其后是该部门的具体数据行(<tbody>)。当用户输入搜索关键词时,我们期望的行为是:

  1. 如果某个<tbody>中的行匹配搜索词,则该行应显示。
  2. 与该匹配行关联的<thead>也应该显示,即使<thead>本身的内容不匹配搜索词。
  3. 如果<thead>本身的内容匹配搜索词,则该<thead>及其所有关联的<tbody>行都应该显示。
  4. 不匹配的<thead>和<tbody>行应被隐藏。

原始的过滤逻辑通常只针对tbody tr元素:

$(document).ready(function() {
  $("#myInput").on("keyup", function() {
    var value = $(this).val().toLowerCase();
    $("#myTable tbody tr").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
    });
  });
});
登录后复制

这种方法的问题在于,它只会根据<tr>的内容来切换其可见性,而不会考虑其父级<thead>。结果是,即使有匹配的<tr>显示出来,其所属的<thead>也可能因为没有直接匹配搜索词而被隐藏,导致表格结构混乱,用户难以理解显示的数据属于哪个分类。

解决方案:利用data-group属性进行逻辑分组

为了解决上述问题,我们可以引入自定义的HTML data属性来建立<thead>和<tbody>之间的逻辑关联。通过为每个<thead>和其对应的<tbody>分配一个相同的data-group值,我们可以在JavaScript中轻松地识别和操作这些分组。

Natural Language Playlist
Natural Language Playlist

探索语言和音乐之间丰富而复杂的关系,并使用 Transformer 语言模型构建播放列表。

Natural Language Playlist 67
查看详情 Natural Language Playlist

1. 修改HTML结构

首先,我们需要修改表格的HTML结构,为每个<thead>和其紧邻的<tbody>添加一个唯一的data-group属性。例如:

<div class="col-md d-inline">
  <input type="text" class="form-control" aria-label="Small" aria-describedby="inputGroup-sizing-sm" placeholder="Meklēt.." id="myInput">
</div>
<table id="myTable" class="table table-sm table-bordered table-hover">
  <!-- 第一个部门 -->
  <thead class="bg-primary" data-group="1">
    <tr>
      <th colspan="3">Information about department</th>
    </tr>
  </thead>
  <tbody data-group="1">
    <tr>
      <td>Name - It</td>
      <td>Phone - 1111111</td>
      <td>E-mail - <a class="__cf_email__" data-cfemail="d7bab6bebb97bab6bebbf9b4b8ba" href="/cdn-cgi/l/email-protection">[email protected]</a></td>
    </tr>
  </tbody>
  <!-- 第二个部门 -->
  <thead class="bg-primary" data-group="2">
    <tr>
      <th colspan="3">Information about department 2</th>
    </tr>
  </thead>
  <tbody data-group="2">
    <tr>
      <td>Name - Finance</td>
      <td>Phone - 1111112</td>
      <td>E-mail - <a class="__cf_email__" data-cfemail="88eee1e6e9e6ebedc8e5e9e1e4a6ebe7e5" href="/cdn-cgi/l/email-protection">[email protected]</a></td>
    </tr>
    <tr>
      <td>Name - Finance2</td>
      <td>Phone - 1111113</td>
      <td>E-mail - <a class="__cf_email__" data-cfemail="197f707778777a7c2b5974787075377a7674" href="/cdn-cgi/l/email-protection">[email protected]</a></td>
    </tr>
  </tbody>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
登录后复制

这里,我们为每个<thead>和<tbody>对分配了一个唯一的data-group值(例如"1", "2"等)。

2. 优化JavaScript过滤逻辑

接下来,我们需要修改JavaScript代码,使其能够利用data-group属性来智能地控制元素的显示。

$(document).ready(function() {
  $("#myInput").on("keyup", function() {
    var value = $(this).val().toLowerCase().trim(); // 获取搜索值并转换为小写,去除首尾空格

    // 遍历表格中的每一个 thead 元素
    $("#myTable thead").each(function() {
      var group = $(this).data("group"); // 获取当前 thead 的 data-group 值
      // 检查 thead 本身的内容是否匹配搜索词
      var isTheadMatched = $(this).text().toLowerCase().indexOf(value) > -1;

      // 构建选择器,查找与当前 thead 具有相同 data-group 的 tbody 中的所有 tr
      var selector = `tbody[data-group='${group}'] tr`;
      var allRows = $('#myTable').find(selector);
      var isAnyRowMatched = false; // 标志,表示当前分组中是否有任何行匹配搜索词

      // 遍历当前分组中的所有 tbody 行
      for (var row of $(allRows)) {
        // 判断当前行是否应该显示:
        // 1. thead 本身匹配搜索词 (isTheadMatched)
        // 2. 或者当前行内容匹配搜索词
        const isRowMatched = isTheadMatched || $(row).text().toLowerCase().indexOf(value) > -1;
        $(row).toggle(isRowMatched); // 切换行的显示/隐藏

        // 如果当前行内容匹配搜索词(即使 thead 不匹配),则标记此分组有匹配项
        if ($(row).text().toLowerCase().indexOf(value) > -1) {
          isAnyRowMatched = true;
        }
      }

      // 切换当前 thead 的显示/隐藏:
      // 如果 thead 本身匹配搜索词,或者其关联的 tbody 中有任何行匹配搜索词,则显示 thead
      $(this).toggle(isTheadMatched || isAnyRowMatched);
    });
  });
});
登录后复制

代码解析:

  1. 事件监听与预处理: 当用户在搜索框输入时触发keyup事件,获取输入值并转换为小写,并使用trim()去除可能存在的首尾空格,确保搜索的准确性。
  2. 遍历<thead>: 代码不再直接操作<tbody>,而是遍历表格中的每一个<thead>元素。
  3. 获取分组信息: 对于每个<thead>,获取其data-group属性值,这将用于定位其对应的<tbody>。
  4. <thead>自身匹配判断: 检查当前<thead>的文本内容是否包含搜索词。
  5. 查找关联<tbody>行: 使用data-group值构建一个选择器(例如tbody[data-group='1'] tr),精确地找到与当前<thead>关联的所有<tbody>行。
  6. <tbody>行匹配判断与显示:
    • 遍历这些关联的<tbody>行。
    • 对于每一行,判断它是否应该显示:如果<thead>本身匹配搜索词,或者当前行匹配搜索词,则该行显示。
    • 同时,使用isAnyRowMatched标志记录当前分组中是否有任何<tbody>行匹配搜索词。
  7. <thead>显示逻辑: 最后,根据以下条件切换当前<thead>的显示状态:
    • <thead>本身匹配搜索词 (isTheadMatched)。
    • 或者,其关联的<tbody>中有任何一行匹配搜索词 (isAnyRowMatched)。 只要满足其中一个条件,<thead>就会显示,否则隐藏。

完整示例代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Filter Table Data with Thead</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<style>
  /* 仅为示例增加一些样式 */
  body { padding: 20px; }
  .table-hover tbody tr:hover {
    background-color: #f5f5f5;
  }
</style>
</head>
<body>

<div class="container">
  <h2 class="mb-4">带有分组标题的表格数据过滤</h2>

  <div class="col-md-4 mb-3">
    <input type="text" class="form-control" placeholder="输入关键词搜索..." id="myInput">
  </div>

  <table id="myTable" class="table table-sm table-bordered table-hover">
    <!-- 第一个部门 -->
    <thead class="bg-primary text-white" data-group="1">
      <tr>
        <th colspan="3">部门信息:IT部</th>
      </tr>
    </thead>
    <tbody data-group="1">
      <tr>
        <td>姓名 - Tom</td>
        <td>电话 - 1111111</td>
        <td>邮箱 - tom@example.com</td>
      </tr>
      <tr>
        <td>姓名 - Jerry</td>
        <td>电话 - 1111112</td>
        <td>邮箱 - jerry@example.com</td>
      </tr>
    </tbody>

    <!-- 第二个部门 -->
    <thead class="bg-success text-white" data-group="2">
      <tr>
        <th colspan="3">部门信息:财务部</th>
      </tr>
    </thead>
    <tbody data-group="2">
      <tr>
        <td>姓名 - Alice</td>
        <td>电话 - 2222221</td>
        <td>邮箱 - alice@example.com</td>
      </tr>
      <tr>
        <td>姓名 - Bob</td>
        <td>电话 - 2222222</td>
        <td>邮箱 - bob@example.com</td>
      </tr>
      <tr>
        <td>姓名 - Bob Junior</td>
        <td>电话 - 2222223</td>
        <td>邮箱 - bobjr@example.com</td>
      </tr>
    </tbody>

    <!-- 第三个部门 -->
    <thead class="bg-info text-white" data-group="3">
      <tr>
        <th colspan="3">部门信息:市场部</th>
      </tr>
    </thead>
    <tbody data-group="3">
      <tr>
        <td>姓名 - Carol</td>
        <td>电话 - 3333331</td>
        <td>邮箱 - carol@example.com</td>
      </tr>
    </tbody>
  </table>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
  $("#myInput").on("keyup", function() {
    var value = $(this).val().toLowerCase().trim();

    $("#myTable thead").each(function() {
      var group = $(this).data("group");
      var isTheadMatched = $(this).text().toLowerCase().indexOf(value) > -1;

      var selector = `tbody[data-group='${group}'] tr`;
      var allRows = $('#myTable').find(selector);
      var isAnyRowMatched = false;

      for (var row of $(allRows)) {
        const isRowMatched = isTheadMatched || $(row).text().toLowerCase().indexOf(value) > -1;
        $(row).toggle(isRowMatched);
        if ($(row).text().toLowerCase().indexOf(value) > -1) {
          isAnyRowMatched = true;
        }
      }

      $(this).toggle(isTheadMatched || isAnyRowMatched);
    });
  });
});
</script>

</body>
</html>
登录后复制

注意事项与最佳实践

  • data-group值的唯一性: 确保每个<thead>和其对应的<tbody>的data-group值是唯一的,以便正确关联。
  • 性能考量: 对于包含成千上万个<thead>和<tbody>分组的巨型表格,每次keyup事件都遍历所有<thead>和<tbody>可能会有性能开销。可以考虑:
    • 防抖(Debounce): 限制keyup事件触发的频率,例如在用户停止输入一段时间后才执行搜索。
    • 虚拟滚动(Virtual Scrolling): 如果表格行数极其庞大,只渲染视口内的行,这会使过滤逻辑更复杂但性能更高。
  • 用户体验: 可以在搜索框旁边添加一个清除按钮,方便用户快速清空搜索内容并恢复表格的完整视图。
  • 可访问性: 确保过滤功能对屏幕阅读器等辅助技术是可访问的。
  • 多语言支持: 如果表格内容是多语言的,确保搜索逻辑能够处理不同语言的字符集。

总结

通过巧妙地利用HTML的data-group属性来建立<thead>和<tbody>之间的逻辑关联,并结合jQuery的遍历和选择器功能,我们成功实现了一个功能强大且用户友好的表格数据过滤方案。这个方案不仅能够精确地过滤数据行,还能智能地管理其所属标题的可见性,极大地提升了复杂表格的可读性和交互体验。这种分组过滤的思路同样可以应用于其他需要结构化内容筛选的场景。

以上就是基于data-group属性实现带标题的表格数据过滤的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号