首页 > 解决方案 > 为什么我的搜索没有检查所有标签元素?引导程序,JS

问题描述

几乎绝对是菜鸟,正在使用 bootstrap 和 JS 进行我的第二个项目。所以我制作了搜索表格和几张卡片,每张卡片都有两段。

<div class="container">
    <div class="row justify-content-center my-5">
        <input class="form-control col-xs-12 col-lg-10 col-sm-8" id="myInput" type="text" onkeyup="myFunction()" placeholder="Поиск">
        <button class="btn btn-outline ml-2 my-xs-2 col-xs-8 " style="font-family: Arial, Helvetica, sans-serif; font-weight: 700;">SEARCH</button>
    </div>
</div>
<div class="container">
    <ul class="row" id="myList" style="list-style-type: none;">
        <li class="card mb-4 box-shadow"><p>Adele</p><p>2001</p></li>
        <li class="card mb-4 box-shadow"><p>Agnes</p><p>1980</p></li>

        <li class="card mb-4 box-shadow"><p>Billy</p><p>2010</p></li>
        <li class="card mb-4 box-shadow"><p>Bob</p><p>1530</p></li>

        <li class="card mb-4 box-shadow"><p>Calvin</p></li>
        <li class="card mb-4 box-shadow"><p>Christina</p></li>
        <li class="card mb-4 box-shadow"><p>Cindy</p></li>
    </ul>
</div>

我的脚本:

function myFunction() {
      var input, filter, ul, li, p, i, txtValue;
      input = document.getElementById('myInput');
      filter = input.value.toUpperCase();
      ul = document.getElementById("myList");
      li = ul.getElementsByTagName('li');
    
      for (i = 0; i < li.length; i++) {
        p = li[i].getElementsByTagName("p")[0];
        txtValue = p.textContent || p.innerText;
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
          li[i].style.display = "";
        } else {
          li[i].style.display = "none";
        }
      }
    }

当我输入名称时它可以工作,但是当我输入年份时 - 不。为什么它忽略第二段,我应该如何更改脚本来解决问题?

标签: javascriptsearchfilterbootstrap-4

解决方案


正如 Rich DeBourke 所提到的,问题在于在这一行使用 0 索引:

p = li[i].getElementsByTagName("p")[0];

我建议您使用以下方法:

function myFunction() {
  const input = document.getElementById("myInput");
  const inputValue = input.value.toUpperCase();

  const ul = document.getElementById("myList");
  const lis = ul.getElementsByTagName("li");

  for (let li of lis) {
    const [pName, pYear] = li.getElementsByTagName("p");

    // We assume on this example that the name's paragraph 
    // will always exist, but the year may not
    const textPName = pName.innerText.toUpperCase();
    const textPYear = pYear?.innerText.toUpperCase();

    if (
      textPName.startsWith(inputValue) ||
      (textPYear && textPYear.startsWith(inputValue))
    ) {
      li.style.display = "block";
    } else {
      li.style.display = "none";
    }
  }
}

这种新方法的一些优点是:

  • 变量被定义得更接近它们被使用的地方,并且被赋予的名称与它们在方法中的身份更紧密地耦合在一起。
  • 我们在适当的地方使用 const 而不是 var。
  • 我们使用 for/of 而不是基本的 for 循环,因为我们不需要索引。
  • 我们将 li 数组的元素解构为可以立即使用的合理命名的变量。
  • 我们在 if 语句中考虑边缘情况(年份可能不存在)。
  • 我们在获取元素的内容时使用 innerText(更简单的替代方法),并在 if 语句中将显示设置为阻塞(而不是空字符串),因为这是默认显示。

希望这可以帮助!


推荐阅读