【问题标题】:JS: current node in for-loopJS:for循环中的当前节点
【发布时间】:2021-07-20 20:03:55
【问题描述】:

我有以下 HTML 代码:

<input type="text" id="X1" onkeyup="xFilter()"/>
<table id="table1" class="sort">
  <tr>
    <td>X: A</td>
    <td>Y: A</td>
    <td>Z: A</td>
  </tr>
  <tr>
    <td>X: B</td>
    <td>Y: B</td>
    <td>Z: B</td>
  </tr>
</table>

<input type="text" id="X2" onkeyup="xFilter()"/>
<table id="table2" class="sort">
  <tr>
    <td>X: A</td>
    <td>Y: A</td>
    <td>Z: A</td>
  </tr>
  <tr>
    <td>X: B</td>
    <td>Y: B</td>
    <td>Z: B</td>
  </tr>
</table>

我想每次都使用函数 xFilter() 过滤表列 X。一个例子:我在第一个输入窗口(id="X1")中输入“A”并在第一个表(id="1")中获取第一行。第二张表保持不变。另一个例子:我在第二个输入窗口(id="X2")中输入“B”并在第二个表(id="2")中获取第二行。第一个表保持不变。

以下代码可以正常工作,但不够精简,因为我的页面上有很多表格和很多过滤器选项。

function XFilter1() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("X1");
  filter = input.value.toUpperCase();
  table = document.getElementById("table1");
  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";
      }
    }       
  }
}

function xFilter2() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("X2");
  filter = input.value.toUpperCase();
  table = document.getElementById("table2");
  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";
      }
    }       
  }
}

现在,当我尝试合并这两个函数时,根本没有任何效果,不幸的是我没有看到我的错误。由于我刚开始使用 JavaScript,我希望您的支持能够从我的错误中吸取教训。已经非常感谢了。

function gpvFilter() {
  var tables = document.querySelectorAll("table.sortierbar");
  var inputs = document.querySelectorAll("input.gpvInput");
  for (i = 0; i < tables.length; i++) {
    var input = inputs[i];
    var filter = input.value.toUpperCase();
    var table = tables[i];
    var tr = table.getElementsByTagName("tr");
    for (j = 0; j < tr.length; j++) {
      var td = tr[j].getElementsByTagName("td")[1];
      if (td) {
        var txtValue = td.textContent || td.innerText;
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
          tr[i].style.display = "";
        } else {
          tr[i].style.display = "none";
        }
      }
    }
  }

【问题讨论】:

  • 您在两个循环中使用了相同的变量i。使用不同的变量。另外,请记住将变量声明为函数的本地变量。
  • 感谢您的评论。我已经更正了上面的代码,但没有任何成功。

标签: javascript arrays for-loop


【解决方案1】:

这是一个可以解决问题的自制过滤器。为了将输入与表格相关联,我将它们放在同一个 div 中并使用closest('div').querySelector('table')

window.addEventListener('DOMContentLoaded', () => {

  document.querySelectorAll('.t-filter').forEach(el => el.addEventListener('input', e => {
  // for each of the inputs with class .t-filter...
    let trs = e.target.closest('div').querySelector('table').querySelectorAll('tr');
    // gather together all the <tr>'s in the closest table to me

    trs.forEach(tr => {
      let match = false
      // iterate through each tr. Set match to false as a default
      tr.querySelectorAll('td').forEach(td => {
        if (td.innerText.toLowerCase().includes(e.target.value.toLowerCase())) match = true;
      });
      // in this tr, iterate through all of it's td tags. If the innerText of any one of them contains the search term (case insensitive) set match to true
      if (match || e.target.value.trim() === '') tr.removeAttribute('hidden');
      else tr.setAttribute('hidden', true);
      
      // if there is a match, or we've cleared our input remove the hidden attribute from the tr
      // otherwise add the hidden attribute to the tr
    });

  }))
})
<div>
  <input type="text" class='t-filter' id="X1" />
  <table id="table1" class="sort">
    <tr>
      <td>X: A</td>
      <td>Y: A</td>
      <td>Z: A</td>
    </tr>
    <tr>
      <td>X: B</td>
      <td>Y: B</td>
      <td>Z: B</td>
    </tr>
  </table>
</div>
<div>
  <input type="text" class='t-filter' id="X2" />
  <table id="table2" class="sort">
    <tr>
      <td>X: A</td>
      <td>Y: A</td>
      <td>Z: A</td>
    </tr>
    <tr>
      <td>X: B</td>
      <td>Y: B</td>
      <td>Z: B</td>
    </tr>
  </table>
</div>

【讨论】:

  • 非常感谢,您的代码有效。现在我只需要了解你在那里做了什么;)
  • 没有问题。如果您有兴趣,我在代码中添加了解释
  • 是的,这对我很有帮助——尤其是对我这个 JS 初学者来说;)
猜你喜欢
  • 1970-01-01
  • 2018-05-22
  • 2016-04-02
  • 1970-01-01
  • 2013-09-17
  • 1970-01-01
  • 2015-10-26
  • 1970-01-01
  • 2012-08-10
相关资源
最近更新 更多