我试图使用纯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>

最佳答案

您可以检查每个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>

08-27 20:45