我正在尝试在JS中创建一个函数来搜索HTML表中的<td>标记,但是如果我在其中使用任何<th> </th>标记,则无法正常运行

时间:2019-08-08 23:30:00

标签: javascript html html-table

编辑:没关系,我只是通过将标头做成一个单独的表格来容纳所有标签来解决我的问题

所以我有一个HTML表格,我想有一个搜索栏来搜索该表格,因为它很大。我尝试从W3学校教程(https://www.w3schools.com/howto/howto_js_filter_lists.asp)复制代码,并对其进行了修改并可以在表格中使用,但前提是我不使用任何包含标签的行。

这是我当前正在工作的代码(我注释掉了困扰我的代码段):

<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
    
    <table id="myUL" class="BuyBooksTable">
        <!--<tr>
            <th colspan="3">Books</th>
        </tr>
        <tr>
            <th>Item</th>
            <th>Price</th>
            <th>Purchase Item</th>
        </tr> -->
        <div id="myULSmaller">
        <tr>
            <td>Alice</td>
            <td>Price</td>
            <td>Purchase Item</td>
        </tr>
        <tr>
            <td>Bob</td>
            <td>Price</td>
            <td>Purchase Item</td>
        </tr>
        <tr>
            <td>Carol</td>
            <td>Price</td>
            <td>Purchase Item</td>
        </tr>
        </div>
    </table>

<script>
    function myFunction() {
            // Declare variables
        var input, filter, ul, li, a, i, txtValue;
        input = document.getElementById('myInput');
        filter = input.value.toUpperCase();
        ul = document.getElementById("myUL");
        li = ul.getElementsByTagName('tr');

        // Loop through all list items, and hide those who don't match the search query
        for (i = 0; i < li.length; i++) {
            a = li[i].getElementsByTagName("td")[0];
            txtValue = a.textContent || a.innerText;
            if (txtValue.toUpperCase().indexOf(filter) > -1) {
            li[i].style.display = "";
            } else {
            li[i].style.display = "none";
            }
        }
    }
</script>

4 个答案:

答案 0 :(得分:2)

使用querySelectorAll

此外,您可以使用<tbody>而不是在div中放入table

function myFunction(e) {
  let searchTerm = e.value.toLocaleLowerCase();

  var trs = document.querySelectorAll('table tbody tr');
  [].forEach.call(trs, function(tr) { // all trs
    [].forEach.call(tr.children, function(td) { // all tds
      if (td.getAttribute('search')) { // check if the td needs to be considers for search criteria
        if (td.innerText.toLocaleLowerCase().includes(searchTerm)) {
          tr.style.display = "";
        } else {
          tr.style.display = "none";
        }
      }
    });
  });

}
<input type="text" id="myInput" onkeyup="myFunction(this)" placeholder="Search for names.." title="Type in a name">

<table id="myUL" class="BuyBooksTable">
  <tr>
    <th colspan="3">Books</th>
  </tr>
  <tr>
    <th>Item</th>
    <th>Price</th>
    <th>Purchase Item</th>
  </tr>
  <tbody>
    <tr>
      <td search="true">Alice</td>
      <td>Price</td>
      <td>Purchase Item</td>
    </tr>
    <tr>
      <td search="true">Bob</td>
      <td>Price</td>
      <td>Purchase Item</td>
    </tr>
    <tr>
      <td search="true">Carol</td>
      <td>Price</td>
      <td>Purchase Item</td>
    </tr>
  </tbody>
</table>

答案 1 :(得分:1)

您需要检查a行中的值a = li[i].getElementsByTagName("td")[0];是否存在。试试这个:

<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
    
    <table id="myUL" class="BuyBooksTable">
        <tr>
            <th colspan="3">Books</th>
        </tr>
        <tr>
            <th>Item</th>
            <th>Price</th>
            <th>Purchase Item</th>
        </tr>
        <div id="myULSmaller">
        <tr>
            <td>Alice</td>
            <td>Price</td>
            <td>Purchase Item</td>
        </tr>
        <tr>
            <td>Bob</td>
            <td>Price</td>
            <td>Purchase Item</td>
        </tr>
        <tr>
            <td>Carol</td>
            <td>Price</td>
            <td>Purchase Item</td>
        </tr>
        </div>
    </table>

<script>
    function myFunction() {
            // Declare variables
        var input, filter, ul, li, a, i, txtValue;
        input = document.getElementById('myInput');
        filter = input.value.toUpperCase();
        ul = document.getElementById("myUL");
        li = ul.getElementsByTagName('tr');

        // Loop through all list items, and hide those who don't match the search query
        for (i = 0; i < li.length; i++) {
            a = li[i].getElementsByTagName("td")[0];
            //If a doesn't exist, carry on looping:
            if (!a) {
              continue;
            }
            txtValue = a.textContent || a.innerText;
            if (txtValue.toUpperCase().indexOf(filter) > -1) {
            li[i].style.display = "";
            } else {
            li[i].style.display = "none";
            }
        }
    }
</script>

答案 2 :(得分:0)

只需使用:nth-​​child (n + 3)选择器

document.querySelectorAll('#myUL tr:nth-child(n+3)')

或编辑代码,如

...
//ul = document.getElementById("myUL");
ul = document.getElementById("myULSmaller");
...

或使用此

let trs = document.querySelectorAll('#myUL tr:nth-child(n+3)');
function myFunction() {
    let filter = this.value.trim().toLowerCase();
    let emptyStr = filter.length == 0;


    trs.forEach(function(el) {
        el.style.display = emptyStr || el.textContent.toLowerCase().includes(filter)?"":"none";
    });
}

答案 3 :(得分:0)

Nidhins的答案很好,但是如果您需要搜索所有列,则需要对其进行修改。

我包含一个变量来跟踪行中是否有任何单元格匹配。高亮显示该单元格并显示行

//Set event listener
document.getElementById("myInput").addEventListener("keyup",function(){
  var normalisedSearch = this.value.toLocaleLowerCase();
  //Grab the search tr in the table body
  var searchTrs = document.querySelectorAll("#myUL>tbody>tr");  
  //iterate the cells in the tr
  [].forEach.call(searchTrs,function(tr){
    var visible = false;
    //iterate the cells in the row
    var searchTds = tr.querySelectorAll("td");
    [].forEach.call(searchTds, function(td){
      if(td.innerText.toLocaleLowerCase().includes(normalisedSearch)){
        visible = true;        
        td.style.backgroundColor = normalisedSearch !== "" ? "#CCC" : "";
      }else{
       td.style.backgroundColor = "";
      }
    });    
    //Sit vidibility of the row
    tr.style.display = visible ? "" : "none";    
  });
});
<input type="text" id="myInput" placeholder="Search for names.." title="Type in a name">

<table id="myUL" class="BuyBooksTable">
  <tr>
    <th colspan="3">Books</th>
  </tr>
  <tr>
    <th>Item</th>
    <th>Price</th>
    <th>Purchase Item</th>
  </tr>
  <tbody>
    <tr>
      <td>Alice</td>
      <td>20</td>
      <td>Purchase Item</td>
    </tr>
    <tr>
      <td>Bob</td>
      <td>15</td>
      <td>Purchase Item</td>
    </tr>
    <tr>
      <td>Carol</td>
      <td>2</td>
      <td>Purchase Item</td>
    </tr>
  </tbody>
</table>