首页 > 解决方案 > 如果有内部表,则使用纯 JavaScript 过滤或搜索

问题描述

我试图使用纯 javascript 制作搜索功能。我有一个小代码片段要处理。但是,如果我们在多个 tr 中有内部表,这将不起作用。我们怎样才能做到这一点?

<!DOCTYPE html>
<html>
<head></head>
<body>
  <input type="text" size = "4" id="myInput" onkeyup="myFunction()">
  <table id="myTable">
    <tr>
      <td>Alfreds Futterkiste</td>
      <td>Germany</td>
    </tr>
    <tr>
      <td>Koniglich Essen</td>
      <td>Germany</td>
    </tr>
  </table>

  <script>
    function myFunction() {
      var input, filter, table, tr, td, i, txtValue;
      input = document.getElementById("myInput");
      filter = input.value.toUpperCase();
      table = document.getElementById("myTable");
      tr = table.getElementsByTagName("tr");

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

        if (td) {
          txtValue = td.textContent || td.innerText;  
          if (txtValue.toUpperCase().indexOf(filter) > -1) {
            tr[i].style.display = "";
          } else {
            tr[i].style.display = "none";
          }
        }       
      }
    }
  </script>
</body>
</html>

如果我的 HTML 如下所示,为什么此脚本功能不起作用

<table id="myTable">
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Koniglich Essen</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>
    <table>
      <tr>
        <td>USA</td>
      </tr>
      <tr>
        <td>UK</td>
      </tr>
    </table>
   </td>
  </tr>
</table>

标签: javascripthtml

解决方案


您可以检查每个 td 的内容以查看它是否包含一个表格,然后递归检查该表格以查看其内容是否应显示。我已经用你的一些代码在这里完成了,但我会进一步分解这些功能。

此代码返回内部表是否完全隐藏或不用作隐藏包含内部表的行的逻辑的一部分的布尔表示。如果内表被隐藏但行中的另一个元素未隐藏,则内表行将再次显示。

function myFunction() {
  const input = document.getElementById("myInput"),
    filter = input.value.toUpperCase(),
    table = document.getElementById("myTable");

  filterTableRows(table, filter)

}

function filterTableRows(table, filter) {
  const rows = table.getElementsByTagName('tr');
  let hiddenRows = 0;

  for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {

    let show = false;
    const columns = rows[rowIndex].getElementsByTagName('td');

    for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) {

      const innerTables = columns[columnIndex].getElementsByTagName('table');

      if (innerTables.length) {
        for (let tableIndex = 0; tableIndex < innerTables.length; tableIndex++) {
          if ( ! filterTableRows(innerTables[tableIndex], filter)) {
            show = true;
          }
        }
      } else {
        let txtValue = columns[columnIndex].textContent || columns[columnIndex].innerText;
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
          show = true;
        }

      }
    }

    if (show) {
      rows[rowIndex].style.display = "";
      for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) {
        const innerTables = columns[columnIndex].getElementsByTagName('table');
        if (innerTables.length) {
          for (let tableIndex = 0; tableIndex < innerTables.length; tableIndex++) {
            showTable(innerTables[tableIndex]);
          }
        }
      }
    } else {
      rows[rowIndex].style.display = "none";
      hiddenRows++;
    }

  }


  return hiddenRows == rows.length;
}

function showTable(table) {
  const rows = table.getElementsByTagName('tr');
  for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
    rows[rowIndex].style.display = "";
  }
}
<!DOCTYPE html>
<html>

<head></head>

<body>
  <input type="text" size="4" id="myInput" onkeyup="myFunction()">
  <table id="myTable">
    <tr>
      <td>Alfreds Futterkiste</td>
      <td>Germany</td>
    </tr>
    <tr>
      <td>Koniglich Essen</td>
      <td>Germany</td>
    </tr>
    <tr>
      <td>
        <table>
          <tr>
            <td>Pierre Truffant</td>
          </tr>
        </table>
      </td>
      <td>France</td>
    </tr>
  </table>
</body>

</html>


推荐阅读