You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

原生JS表格筛选失效:所有行均被隐藏的问题排查

表格筛选功能问题排查与修复

问题描述

尝试使用原生JavaScript实现表格筛选功能,通过搜索输入框根据内容过滤表格行,但目前无论搜索字符串是否匹配数据,所有表格行都会被隐藏。

原实现代码

JavaScript

function searchTable() {
  var input, filter, table, tr, tds, i, txt
  input = document.querySelector(".search-box")
  filter = input.value.toUpperCase()
  table = document.querySelector(".table-search")
  tr = table.querySelectorAll("tr")

  for (i = 0; i < tr.length; i++) {
    tds = Array.from(tr[i].getElementsByTagName("td"))

    if (tds.length) {
      tds.forEach(function(td) {
        txt = (td.textContent || td.innerText).toUpperCase()
        console.log(txt);
        if (!txt.includes(filter)) {
          console.log('hide')
          tr[i].classList.add("d-none")
        } else {
          console.log('show')
          tr[i].classList.remove("d-none")
        }
      })
    }
  }
}

CSS

.card-header {
  display: flex;
  align-items: center;
}

.search-box {
  border-color: #ccc !important;
  border-left: none;
  padding-left: 0;
}

.search-box:focus {
  box-shadow: none;
}

.btn-search {
  background: #fff !important;
  opacity: 1 !important;
  border-color: #ccc !important;
  border-right: none;
  padding-left: 10px;
  padding-right: 10px;
}

.table-heading {
  font-size: 1.25rem;
  font-weight: 700;
  margin: 0 15px 0 0;
  line-height: 1;
}

.table th {
  background: #f6f6f6;
}

.table > tbody > tr:nth-child(even of :not([class*="d-none"])) > td {
  background: #f6f6f6;
}

.sort-button {
  border-radius: 3px;
  background: #ccc;
  border: none;
}

.sort-button.active {
  background: #04aa6d;
  color: #fff;
}

.sort-button.desc {
  transform: rotateX(180deg);
}

HTML

<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />

<div class="container-fluid">
  <div class="card overflow-hidden shadow-sm my-2">
    <div class="card-header">
      <h2 class="table-heading">Users</h2>
      <div class="input-group input-group-prepend ms-auto w-75">
        <button class="btn btn-sm btn-search" type="button" disabled>
          <i class="fa-solid fa-magnifying-glass"></i>
        </button>
        <input type="search" class="form-control form-control-sm search-box" placeholder="Search" onkeyup="searchTable()" />
      </div>
    </div>
    <div class="card-body p-0">
      <table class="table table-search m-0">
        <thead>
          <tr>
            <th>Firstname</th>
            <th>Lastname</th>
            <th>Age</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td class="fname">Alan</td>
            <td class="lname">Green</td>
            <td class="age">24</td>
          </tr>
          <tr>
            <td class="fname">Anne</td>
            <td class="lname">Smith</td>
            <td class="age">42</td>
          </tr>
          <tr>
            <td class="fname">Jane</td>
            <td class="lname">Doe</td>
            <td class="age">19</td>
          </tr>
          <tr>
            <td class="fname">July</td>
            <td class="lname">Dooley</td>
            <td class="age">121</td>
          </tr>
          <tr>
            <td class="fname">Mary</td>
            <td class="lname">Moe</td>
            <td class="age">21</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</div>

问题根源

原代码的逻辑错误在于:遍历行内每个<td>时,只要有一个td不匹配搜索关键词,就会给整行添加隐藏类。比如某行有3个td,前两个匹配关键词,第三个不匹配,遍历到第三个td时就会把行隐藏,最终导致所有行都被隐藏——因为几乎没有行的所有td都能匹配任意搜索关键词。

修复方案

调整逻辑:对每一行先默认隐藏,只要找到任意一个匹配关键词的td,就将行设为显示,并且停止遍历该行的其他td,避免后续不匹配的td覆盖显示状态。同时优化遍历范围,只处理<tbody>内的行,跳过表头。

修复后的JavaScript代码

function searchTable() {
  const input = document.querySelector(".search-box");
  const filter = input.value.toUpperCase();
  const table = document.querySelector(".table-search");
  // 只遍历tbody里的行,跳过表头
  const rows = table.querySelectorAll("tbody tr");

  rows.forEach(row => {
    // 默认隐藏行
    row.classList.add("d-none");
    const cells = row.getElementsByTagName("td");
    // 遍历当前行的所有单元格
    for (const cell of cells) {
      const text = (cell.textContent || cell.innerText).toUpperCase();
      if (text.includes(filter)) {
        // 找到匹配项,显示行并跳出循环
        row.classList.remove("d-none");
        break;
      }
    }
  });
}

额外优化点

  1. 使用const/let替代var,符合现代JS规范
  2. 直接遍历<tbody>内的行,避免处理表头的<tr>
  3. 找到匹配项后立即break循环,减少不必要的遍历操作
  4. 简化变量声明,提升代码可读性

内容的提问来源于stack exchange,提问作者Razvan Zamfir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 05:09:51