【问题标题】:How to filter elements using JavaScript filter?如何使用 JavaScript 过滤器过滤元素?
【发布时间】:2018-08-03 14:18:53
【问题描述】:

我正在努力让这个过滤器正常工作。

我已将其设置为根据卡片标题 (h5) 过滤并仅显示搜索的内容。它会过滤掉不需要的标题,但不会过滤掉卡片的其余部分。

为了更好地解释,这里有一个演示 - JS Element Filter

这是代码:

function myFunction() {
    var input, filter, card, h5, a, i;
    input = document.getElementById("myFilter");
    filter = input.value.toUpperCase();
    card = document.getElementById("myItems");
    h5 = card.getElementsByTagName("h5");
    for (i = 0; i < h5.length; i++) {
        a = h5[i].getElementsByTagName("a")[0];
        if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
            h5[i].style.display = "";
        } else {
            h5[i].style.display = "none";
        }
    }
}
.container {
  padding: 10px;
}

ul li {
  list-style: none;
  
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="container">
  <div class="row">
    <div class="col-sm-12 mb-3">
      <input type="text" id="myFilter" class="form-control" onkeyup="myFunction()" placeholder="Search for names..">
    </div>
  </div>
  <div class="row" id="myItems">
    <div class="col-sm-12 mb-3">
      <div class="card">
        <div class="card-body">
          <h5 class="card-title"><a href="#">Card One</a></h5>
          <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
          <p class="card-text">Some text.</p>
        </div>
      </div>

      <div class="card">
        <div class="card-body">
          <h5 class="card-title"><a href="#">Card Two</a></h5>
          <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
          <p class="card-text">Some text.</p>
        </div>
      </div>

      <div class="card">
        <div class="card-body">
          <h5 class="card-title"><a href="#">Card Three</a></h5>
          <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
          <p class="card-text">Some text.</p>
        </div>
      </div>      
    </div>    
  </div>
</div> 

【问题讨论】:

  • 您只隐藏了锚标记。你需要隐藏整个卡块。

标签: javascript search-form


【解决方案1】:

原因

您只是隐藏了标题 (h5.card-title),而不是整个卡片 (div.card)

解决方案

首先获取对整张卡片的引用。然后隐藏该元素而不仅仅是标题。

实施 A

获取对整个卡的引用的快速而肮脏的解决方案是通过parentElement 属性访问它。由于您的&lt;h5&gt; 的父级是card-body,它的父级是您通过h5[i].parentElement.parentElement 访问它的整个卡。

所以将h5[i].style.display 更改为h5[i].parentElement.parentElement.style.display 像这样:

function myFunction() {
    var input, filter, card, h5, a, i;
    input = document.getElementById("myFilter");
    filter = input.value.toUpperCase();
    card = document.getElementById("myItems");
    h5 = card.getElementsByTagName("h5");
    for (i = 0; i < h5.length; i++) {
        a = h5[i].getElementsByTagName("a")[0];
        if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
            h5[i].parentElement.parentElement.style.display = "";
        } else {
            h5[i].parentElement.parentElement.style.display = "none";
        }
    }
}
.container {
  padding: 10px;
}

ul li {
  list-style: none;
  
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="container">
  <div class="row">
    <div class="col-sm-12 mb-3">
      <input type="text" id="myFilter" class="form-control" onkeyup="myFunction()" placeholder="Search for names..">
    </div>
  </div>
  <div class="row" id="myItems">
    <div class="col-sm-12 mb-3">
      <div class="card">
        <div class="card-body">
          <h5 class="card-title"><a href="#">Card One</a></h5>
          <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
          <p class="card-text">Some text.</p>
        </div>
      </div>

      <div class="card">
        <div class="card-body">
          <h5 class="card-title"><a href="#">Card Two</a></h5>
          <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
          <p class="card-text">Some text.</p>
        </div>
      </div>

      <div class="card">
        <div class="card-body">
          <h5 class="card-title"><a href="#">Card Three</a></h5>
          <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
          <p class="card-text">Some text.</p>
        </div>
      </div>      
    </div>    
  </div>
</div> 

实施 B

更强大的解决方案是迭代卡片而不是标题。这样您就可以直接引用卡片,而不必摆弄 parentElements。当您只想搜索文本时,使用 innerText 属性访问卡片标题中的文本字符串也可能很有用。

function myFunction() {
    var input, filter, cards, cardContainer, h5, title, i;
    input = document.getElementById("myFilter");
    filter = input.value.toUpperCase();
    cardContainer = document.getElementById("myItems");
    cards = cardContainer.getElementsByClassName("card");
    for (i = 0; i < cards.length; i++) {
        title = cards[i].querySelector(".card-body h5.card-title a");
        if (title.innerText.toUpperCase().indexOf(filter) > -1) {
            cards[i].style.display = "";
        } else {
            cards[i].style.display = "none";
        }
    }
}
.container {
  padding: 10px;
}

ul li {
  list-style: none;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="container">
  <div class="row">
    <div class="col-sm-12 mb-3">
      <input type="text" id="myFilter" class="form-control" onkeyup="myFunction()" placeholder="Search for names..">
    </div>
  </div>
  <div class="row" id="myItems">
    <div class="col-sm-12 mb-3">
      <div class="card">
        <div class="card-body">
          <h5 class="card-title"><a href="#">Card One</a></h5>
          <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
          <p class="card-text">Some text.</p>
        </div>
      </div>

      <div class="card">
        <div class="card-body">
          <h5 class="card-title"><a href="#">Card Two</a></h5>
          <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
          <p class="card-text">Some text.</p>
        </div>
      </div>

      <div class="card">
        <div class="card-body">
          <h5 class="card-title"><a href="#">Card Three</a></h5>
          <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
          <p class="card-text">Some text.</p>
        </div>
      </div>      
    </div>    
  </div>
</div>

【讨论】:

  • 我知道我在哪里失误了。感谢您的帮助。
【解决方案2】:

您必须隐藏整个卡片容器,而不是仅隐藏标题 (h5)。 例如,快速更正是在标题上使用parentNode

if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
    h5[i].parentNode.style.display = "";
} else {
    h5[i].parentNode.style.display = "none";
}

【讨论】:

    【解决方案3】:

    这里的问题是您只是将display:none 设置为h5,反之亦然,而不是整个卡本身。

    看这里

    function myFunction() {
        var input, filter, card, h5, a, i;
        input = document.getElementById("myFilter");
        filter = input.value.toUpperCase();
        card = document.getElementById("myItems");
        h5 = card.getElementsByTagName("h5");
        for (i = 0; i < h5.length; i++) {
            a = h5[i].getElementsByTagName("a")[0];
            if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
                h5[i].closest(".card").style.display = "";
            } else {
                h5[i].closest(".card").style.display = "none";
            }
        }
    }

    我已对其进行了更改,以便它获得最接近的父级,该父级在此处具有 .card

    h5[i].closest(".card")

    或者,如果您的目标浏览器不支持.closest,您可以使用

    h5[i].parentNode.parentNode.style.display = "none"

    查看我在这里分叉的完整 Codepen:https://codepen.io/anon/pen/gjKgjN

    【讨论】:

      【解决方案4】:

      你隐藏了标题。你要隐藏的是卡片。

      你可以通过 h5[i].parentNode.parentNode 来做到这一点,因为标题在卡片深处嵌套了 2 层。

      如果您的客户端浏览器支持它,您可以使用Closest ancestor matching selector using native DOM?

      或者如果你有 jQuery 供你使用,你可以搜索 $(h5[i]).closest('.card');

      function myFunction() {
          var input, filter, card, h5, a, i;
          input = document.getElementById("myFilter");
          filter = input.value.toUpperCase();
          card = document.getElementById("myItems");
          h5 = card.getElementsByTagName("h5");
          for (i = 0; i < h5.length; i++) {
              var current = h5[i];
              a = current.getElementsByTagName("a")[0];
              if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
                  current.parentNode.parentNode.style.display = "";
              } else {
                  current.parentNode.parentNode.style.display = "none";
              }
          }
      }
      .container {
        padding: 10px;
      }
      
      ul li {
        list-style: none;
        
      }
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
      <div class="container">
        <div class="row">
          <div class="col-sm-12 mb-3">
            <input type="text" id="myFilter" class="form-control" onkeyup="myFunction()" placeholder="Search for names..">
          </div>
        </div>
        <div class="row" id="myItems">
          <div class="col-sm-12 mb-3">
            <div class="card">
              <div class="card-body">
                <h5 class="card-title"><a href="#">Card One</a></h5>
                <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
                <p class="card-text">Some text.</p>
              </div>
            </div>
      
            <div class="card">
              <div class="card-body">
                <h5 class="card-title"><a href="#">Card Two</a></h5>
                <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
                <p class="card-text">Some text.</p>
              </div>
            </div>
      
            <div class="card">
              <div class="card-body">
                <h5 class="card-title"><a href="#">Card Three</a></h5>
                <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
                <p class="card-text">Some text.</p>
              </div>
            </div>      
          </div>    
        </div>
      </div>

      但我实际上建议您使用getElementsByClassName 来获取所有卡片,然后遍历它们,通过类名选择 h5 元素,然后访问 h5 的 innerText,这样就可以看到不可见的文本,例如链接title="some thing cool here" 不会妨碍您。

      请参阅下面的 sn-p。

      function myFunction() {
          var input, filter, myItems, cards, i, current, h5, text;
          input = document.getElementById("myFilter");
          filter = input.value.toUpperCase();
          myItems = document.getElementById("myItems");
          cards = myItems.getElementsByClassName("card");
          
          for (i = 0; i < cards.length; i++) {
              current = cards[i];
              h5 = current.getElementsByClassName('card-title')[0];
              text = h5.innerText.toUpperCase();
              if (text.indexOf(filter) > -1) {
                  current.style.display = "";
              } else {
                  current.style.display = "none";
              }
          }
      }
      .container {
        padding: 10px;
      }
      
      ul li {
        list-style: none;
        
      }
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
      <div class="container">
        <div class="row">
          <div class="col-sm-12 mb-3">
            <input type="text" id="myFilter" class="form-control" onkeyup="myFunction()" placeholder="Search for names..">
          </div>
        </div>
        <div class="row" id="myItems">
          <div class="col-sm-12 mb-3">
            <div class="card">
              <div class="card-body">
                <h5 class="card-title"><a href="#">Card One</a></h5>
                <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
                <p class="card-text">Some text.</p>
              </div>
            </div>
      
            <div class="card">
              <div class="card-body">
                <h5 class="card-title"><a href="#">Card Two</a></h5>
                <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
                <p class="card-text">Some text.</p>
              </div>
            </div>
      
            <div class="card">
              <div class="card-body">
                <h5 class="card-title"><a href="#">Card Three</a></h5>
                <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
                <p class="card-text">Some text.</p>
              </div>
            </div>      
          </div>    
        </div>
      </div>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-16
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 2016-04-28
        • 1970-01-01
        • 2010-10-03
        相关资源
        最近更新 更多