【问题标题】:Filter HTML Table using JavaScript - textContent Error使用 JavaScript 过滤 HTML 表格 - textContent 错误
【发布时间】:2021-07-23 11:08:21
【问题描述】:

期望结果: 将 .csv 文件中的数据输入 PHP。从 .csv 文件中获取数据并存储到数组中。使用 PHP 将数组存储到 HTML 表中。使用搜索引擎使用 JavaScript 过滤行。

我在 JavaScript 中收到以下错误: 未捕获的类型错误:无法读取 null 的属性“textContent”

<script>  
const searchInput = document.getElementById("search");
const rows = document.querySelectorAll("tbody tr");
//console.log(rows);

searchInput.addEventListener("keyup", function (event) { 
    //console.log(event);
    const q = event.target.value.toLowerCase();
       rows.forEach(row => {
          //console.log(row);
        row.querySelector("td").textContent.toLowerCase().startsWith(q); 
        ? (row.style.display = "table-row")
        : (row.style.display = "none");
    } );
});
 </script> 

使用console.log,我已经能够确定它正在正确读取并循环遍历表中的每一行,但它无法循环遍历“td”来确定它是否与搜索引擎中的文本匹配。

如果该信息有用,则在整理行时,该数组是一个 NodeList。

如果需要,很乐意上传更多信息。提前感谢您的帮助!

编辑 添加最小的 HTML。该表包含 15 行,但出于此目的,仅添加了几行。此表是使用 PHP 从数组创建的。

EDIT 2标题添加到广告中

<html>
<head>  
</head> 
    <body>   
    <input type="text" name="search" id="search" placeholder="Search for services..">
    <table>
<thead>
    <tr>
    <th>Item #</th>
    <th>Name</th>
    <th>Type</th>
    <th>Make</th>
    <th>Model</th>
    <th>Brand</th>
    <th>Description</th>
    </tr>
</thead>
<tbody>
    <tr>
    <td>1</td><td>Cut &amp; Blow Dry</td>
    <td>Service</td>
    <td></td>
    <td></td>
    <td>Hair by Cass</td>
    <td>Haircut and style after</td>
    </tr>
    </tbody>
</table>
    </body>
    </html>

【问题讨论】:

  • row.querySelector("td") 只会让您获得一行的第一个 TD 元素。您能否提供带有搜索框的最小 HTML 示例表?
  • 您的 HTML 不是那么有效。 &lt;th&gt; 应该进入 &lt;thead&gt; 而不是 &lt;tbody&gt;
  • 您的第一行不包含任何 td 这就是您收到该错误的原因
  • 我现在也在测试你的代码。我刚刚调整了我的 PHP 循环以在 中包含 。

标签: javascript php html


【解决方案1】:
  • 您的 HTML 表格标记不正确。带有&lt;th&gt;s 的行应该进入&lt;thead&gt; 而不是&lt;tbody&gt;
  • 您使用了无效的三元运算符语法; ? x : y
  • 使用"input" 事件来解决鼠标复制/粘贴等问题。

searchInput.addEventListener("input", function(evt) {
  const q = evt.currentTarget.value.toLowerCase();
  rows.forEach(row => {
    const matches = row.querySelector("td").textContent.toLowerCase().startsWith(q);
    row.style.display = matches ? "table-row" : "none";
  });
});

但请记住,row.querySelector("td") 只会连续获得第一个 TD(不是全部):

使用Array.prototype.some()匹配多个单元格

这是一个示例,可让您搜索任何单元格,并使用Element.classList.toggle()(和.includes() 而不是.startsWith())使用更好的切换解决方案

const EL_search = document.querySelector("#search");
const ELS_rows = document.querySelectorAll("tbody tr");

EL_search.addEventListener("input", function(evt) {
  const q = evt.currentTarget.value.toLowerCase();
  ELS_rows.forEach(TR => {
    const TDS = TR.querySelectorAll("td");
    const matches = [...TDS].some(TD =>TD.textContent.toLowerCase().includes(q));
    TR.classList.toggle("none", !matches);
  });
});
.none {
  display: none;
}
<input type="text" id="search" autocomplete="off">

<table>
  <thead>
    <tr><th>Name</th><th>Surname</th></tr>
  </thead>
  <tbody>
    <tr><td>Ann</td><td>Doe</td></tr>
    <tr><td>Jon</td><td>Doe</td></tr>
    <tr><td>Jonas</td><td>Foe</td></tr>
  </tbody>
</table>

【讨论】:

  • 我已经输入了这个,但由于某种原因它没有在我的代码中过滤。我还调整了 搜索以包含您注意到的内容。但它在这里完美运行。你能解释一下 [...TDS] 的作用吗? (对不起,这里是新手)
  • @casscode 看看我的 HTML。我正确使用了&lt;thead&gt;。确保您也进行调整!
  • @casscode 由于 TDS 是一个 NodeList - 默认情况下它没有 Array.prototype.some() 方法 - 因此通过使用 Spread syntax ... 我正在将类似数组的 NodeList 转换为数组。跨度>
  • 这是有道理的。谢谢你的解释!我得到了这个工作。非常感谢您对此提供的所有帮助!
【解决方案2】:

错误来自row.querySelector("td"),因为它试图在标题tr 元素中查找td,该元素仅包含th 子元素。

修复很简单,在继续之前检查是否找到td

const td = row.querySelector("td");
if (!td)
  return;

td.textContent.toLowerCase().startsWith(q) ?
  (row.style.display = "table-row") :
  (row.style.display = "none");

另外,querySelector 只会返回第一个找到的元素,如果您需要查找所有元素,请使用 querySelectorAll 它将返回元素列表,然后使用 for 循环处理列表中的所有元素。

const tds = row.querySelectorAll("td");

for(let i = 0; i < tds.length; i++)
{
  tds[i].textContent.toLowerCase().startsWith(q) ?
    (row.style.display = "table-row") :
    (row.style.display = "none");
}

【讨论】:

  • 查看他们的 HTML,他们有 trtbody 内只有 th 子级
  • @vanowm 是的,我现在看到了 Q 编辑。这不是最好的 HTML 表格标记。 OP 缺失 &lt;thead&gt;
  • @RokoC.Buljan 是的,你是对的,他们应该修复源而不是治疗症状......
猜你喜欢
  • 2015-11-12
  • 1970-01-01
  • 2018-12-13
  • 2012-02-24
  • 2021-03-24
  • 1970-01-01
  • 1970-01-01
  • 2014-08-11
  • 2015-11-01
相关资源
最近更新 更多