|

JavaScript/CSS 表格搜索功能

实现一个带搜索功能的表格是 Web 开发中常见的需求,允许用户通过输入关键字实时过滤表格行。以下是详细的中文讲解,介绍如何使用 JavaScript 和 CSS 实现表格搜索功能,包含完整代码示例、样式美化、功能说明和注意事项。


1. 功能需求

  • 目标:创建一个可搜索的表格,用户可以在输入框中键入关键字,实时过滤表格行。
  • 功能
  • 搜索框支持对所有列或特定列的实时过滤(大小写不敏感)。
  • 支持鼠标和键盘交互。
  • 提供视觉反馈(如高亮匹配项)。
  • 保持表格样式美观,响应式设计。
  • 技术
  • JavaScript:处理输入事件、过滤逻辑、DOM 操作。
  • CSS:美化表格和搜索框,添加交互效果。

2. 实现步骤

2.1 HTML 结构

  • 使用 <table> 包含表头(<th>)和数据行(<tr>)。
  • 添加搜索输入框,允许用户输入关键字。
  • 示例结构:
  <div class="search-container">
      <input type="text" id="searchInput" placeholder="搜索表格...">
  </div>
  <table id="searchableTable">
      <thead>
          <tr>
              <th>名称</th>
              <th>年龄</th>
              <th>城市</th>
          </tr>
      </thead>
      <tbody>
          <tr>
              <td>Alice</td>
              <td>25</td>
              <td>北京</td>
          </tr>
          <tr>
              <td>Bob</td>
              <td>30</td>
              <td>上海</td>
          </tr>
          <tr>
              <td>Charlie</td>
              <td>20</td>
              <td>广州</td>
          </tr>
          <tr>
              <td>Diana</td>
              <td>28</td>
              <td>深圳</td>
          </tr>
      </tbody>
  </table>
  • 说明
    • <input> 用于搜索输入。
    • 表格包含多列,搜索将匹配所有列的内容。

2.2 CSS 样式

  • 美化表格和搜索框。
  • 添加交互效果(如输入框聚焦、匹配行高亮)。
  • 示例 CSS:
  .search-container {
      margin: 20px auto;
      text-align: center;
      max-width: 600px;
  }
  #searchInput {
      width: 100%;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 4px;
      font-size: 16px;
      box-sizing: border-box;
  }
  #searchInput:focus {
      outline: none;
      border-color: #007bff;
      box-shadow: 0 0 5px rgba(0, 123, 255, 0.3);
  }
  table {
      border-collapse: collapse;
      width: 100%;
      max-width: 600px;
      margin: 20px auto;
      font-family: Arial, sans-serif;
  }
  th, td {
      border: 1px solid #ddd;
      padding: 12px;
      text-align: left;
  }
  th {
      background-color: #f2f2f2;
  }
  tr:nth-child(even) {
      background-color: #f9f9f9;
  }
  tr:hover {
      background-color: #f0f0f0;
  }
  tr.match {
      background-color: #e6f3ff;
  }
  • 说明
    • 搜索框:聚焦效果、圆角边框。
    • 表格:条纹背景、悬停效果。
    • .match 类高亮匹配的行。

2.3 JavaScript 逻辑

  • 逻辑
  1. 监听搜索框的 input 事件,实时过滤表格行。
  2. 遍历每行,检查所有单元格内容是否包含关键字。
  3. 隐藏不匹配的行,显示匹配的行。
  4. 支持大小写不敏感搜索。
  • 代码示例
  document.addEventListener('DOMContentLoaded', () => {
      const searchInput = document.getElementById('searchInput');
      const table = document.getElementById('searchableTable');
      const rows = table.querySelectorAll('tbody tr');

      searchInput.addEventListener('input', () => {
          const query = searchInput.value.toLowerCase().trim();

          rows.forEach(row => {
              const cells = row.querySelectorAll('td');
              let isMatch = false;

              cells.forEach(cell => {
                  if (cell.textContent.toLowerCase().includes(query)) {
                      isMatch = true;
                  }
              });

              row.style.display = isMatch || query === '' ? '' : 'none';
              row.classList.toggle('match', isMatch && query !== '');
          });
      });
  });

3. 完整代码示例

以下是一个完整的 HTML 文件,包含 HTML、CSS 和 JavaScript,实现带搜索功能的表格:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>表格搜索</title>
    <style>
        .search-container {
            margin: 20px auto;
            text-align: center;
            max-width: 600px;
        }
        #searchInput {
            width: 100%;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 16px;
            box-sizing: border-box;
        }
        #searchInput:focus {
            outline: none;
            border-color: #007bff;
            box-shadow: 0 0 5px rgba(0, 123, 255, 0.3);
        }
        table {
            border-collapse: collapse;
            width: 100%;
            max-width: 600px;
            margin: 20px auto;
            font-family: Arial, sans-serif;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 12px;
            text-align: left;
        }
        th {
            background-color: #f2f2f2;
        }
        tr:nth-child(even) {
            background-color: #f9f9f9;
        }
        tr:hover {
            background-color: #f0f0f0;
        }
        tr.match {
            background-color: #e6f3ff;
        }
    </style>
</head>
<body>
    <div class="search-container">
        <input type="text" id="searchInput" placeholder="搜索表格...">
    </div>
    <table id="searchableTable">
        <thead>
            <tr>
                <th>名称</th>
                <th>年龄</th>
                <th>城市</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Alice</td>
                <td>25</td>
                <td>北京</td>
            </tr>
            <tr>
                <td>Bob</td>
                <td>30</td>
                <td>上海</td>
            </tr>
            <tr>
                <td>Charlie</td>
                <td>20</td>
                <td>广州</td>
            </tr>
            <tr>
                <td>Diana</td>
                <td>28</td>
                <td>深圳</td>
            </tr>
        </tbody>
    </table>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const searchInput = document.getElementById('searchInput');
            const table = document.getElementById('searchableTable');
            const rows = table.querySelectorAll('tbody tr');

            searchInput.addEventListener('input', () => {
                const query = searchInput.value.toLowerCase().trim();

                rows.forEach(row => {
                    const cells = row.querySelectorAll('td');
                    let isMatch = false;

                    cells.forEach(cell => {
                        if (cell.textContent.toLowerCase().includes(query)) {
                            isMatch = true;
                        }
                    });

                    row.style.display = isMatch || query === '' ? '' : 'none';
                    row.classList.toggle('match', isMatch && query !== '');
                });
            });
        });
    </script>
</body>
</html>

4. 代码说明

  • HTML
  • .search-container 包含搜索输入框。
  • <table> 包含表头(名称、年龄、城市)和数据行。
  • CSS
  • 搜索框:聚焦效果、圆角边框。
  • 表格:条纹背景、边框、悬停效果。
  • .match 类高亮匹配行,增强用户体验。
  • JavaScript
  • 事件监听:监听 input 事件,实时响应用户输入。
  • 过滤逻辑
    • 获取输入框的值,转换为小写(大小写不敏感)。
    • 遍历每行,检查所有 <td> 是否包含关键字(使用 includes)。
    • 显示匹配行,隐藏不匹配行。
  • 高亮效果:为匹配行添加 .match 类,显示蓝色背景。
  • 空输入处理:当搜索框为空时,显示所有行。

5. jQuery 实现(可选)

如果项目已使用 jQuery,可以简化 DOM 操作。以下是 jQuery 版本的代码:

$(document).ready(function() {
    const $searchInput = $('#searchInput');
    const $rows = $('#searchableTable tbody tr');

    $searchInput.on('input', function() {
        const query = $searchInput.val().toLowerCase().trim();

        $rows.each(function() {
            const $cells = $(this).find('td');
            let isMatch = false;

            $cells.each(function() {
                if ($(this).text().toLowerCase().includes(query)) {
                    isMatch = true;
                }
            });

            $(this).toggle(isMatch || query === '');
            $(this).toggleClass('match', isMatch && query !== '');
        });
    });
});
  • 依赖:需引入 jQuery:
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

6. 方法对比

方法/特点描述优点缺点
原生 JavaScript使用 DOM 操作和事件处理实现无依赖,性能好,灵活代码稍复杂
jQuery使用 jQuery 简化 DOM 和事件处理代码简洁,适合 jQuery 项目需引入 jQuery,增加加载时间
第三方库(如 DataTables)使用现成库实现搜索和排序功能丰富,支持分页、排序等体积大,可能过度复杂

DataTables 示例(简单配置):

<link href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css" rel="stylesheet">
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<script>
    $(document).ready(function() {
        $('#searchableTable').DataTable();
    });
</script>
  • 说明:DataTables 提供开箱即用的搜索、排序和分页,但需引入 jQuery 和 DataTables 库。

7. 注意事项

  • 搜索逻辑
  • 使用 toLowerCaseincludes 实现大小写不敏感的简单匹配。
  • 可扩展支持正则表达式或模糊搜索:
    javascript const regex = new RegExp(query, 'i'); if (regex.test(cell.textContent)) isMatch = true;
  • 性能
  • 小表格(<100 行):原生或 jQuery 性能足够。
  • 大表格(>1000 行):考虑分页或虚拟化(如 DataTables)。
  • 浏览器兼容性
  • querySelectorAllincludes 是 ES5 标准,现代浏览器全支持。
  • IE11 需确保 textContent 兼容性。
  • 用户体验
  • 高亮匹配行(.match 类)提高可读性。
  • 添加防抖(debounce)优化频繁输入:
    javascript let timeout; searchInput.addEventListener('input', () => { clearTimeout(timeout); timeout = setTimeout(() => filterRows(), 300); });
  • 支持特定列搜索:为每列添加单独输入框,修改过滤逻辑。
  • 扩展性
  • 动态数据:通过 AJAX 加载 JSON 数据:
    javascript fetch('data.json').then(res => res.json()).then(data => { const tbody = table.querySelector('tbody'); tbody.innerHTML = data.map(row => `<tr><td>${row.name}</td><td>${row.age}</td><td>${row.city}</td></tr>`).join(''); });
  • 结合排序功能:参考之前的表格排序实现。
  • 安全性
  • 用户输入需转义,防止 XSS:
    javascript const safeQuery = query.replace(/[<>]/g, '');

8. 总结

  • 实现方式:原生 JavaScript + CSS 实现轻量、灵活的表格搜索。
  • 核心逻辑
  • 监听 input 事件,实时过滤行。
  • 检查所有单元格,显示匹配行并高亮。
  • CSS 提供美观样式和交互反馈。
  • 替代方案
  • jQuery:简化 DOM 操作。
  • DataTables:功能丰富,适合复杂需求。
  • 选择依据
  • 小型项目:原生 JavaScript。
  • jQuery 项目:使用 jQuery 简化代码。
  • 高级功能:考虑 DataTables 或框架集成(如 React Table)。
  • 测试:验证搜索功能(大小写、部分匹配)、高亮效果和交互流畅性。

如果需要扩展功能(如特定列搜索、结合排序、动态数据加载、React/Vue 集成),或有其他问题,请提供更多细节,我可以进一步优化回答!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注