我正在尝试使用html,javascript和bootstrap 4创建可搜索的卡片,但是我的代码无法正常工作。我想要的是根据它们的标题(h5.card-title
)和标签(a.badge
)用搜索栏过滤这三张卡片。
以下是HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="filter.js"></script>
</head>
<body>
<input type="text" id="myFilter" class="form-control" onkeyup="myFunction()" placeholder="Search for names..">
<div class="container">
<div id="myItems">
<div class="row">
<div class="p-3">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="..." alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Title One</h5>
<div class="btn-group" role="group" aria-label="Button group with nested dropdown">
<button type="button" class="btn btn-primary">Button</button>
<div class="btn-group" role="group">
<button id="btnGroupDrop1" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
</button>
<div class="dropdown-menu" aria-labelledby="btnGroupDrop1">
<a class="dropdown-item" href="#">Option 1</a>
<a class="dropdown-item" href="#">Option 2</a>
</div>
</div>
</div>
</div>
<div class="card-footer">
<a href="#" class="badge badge-secondary">first tag</a>
<a href="#" class="badge badge-secondary">second tag</a>
</div>
</div>
</div>
<div class="p-3">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="..." alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Title Two</h5>
<div class="btn-group" role="group" aria-label="Button group with nested dropdown">
<button type="button" class="btn btn-primary">Button</button>
<div class="btn-group" role="group">
<button id="btnGroupDrop2" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button>
<div class="dropdown-menu" aria-labelledby="btnGroupDrop1">
<a class="dropdown-item" href="#">Option 1</a>
<a class="dropdown-item" href="#">Option 2</a>
</div>
</div>
</div>
</div>
<div class="card-footer">
<a href="#" class="badge badge-secondary">different tag</a>
<a href="#" class="badge badge-secondary">unique tag</a>
</div>
</div>
</div>
<div class="p-3">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="..." alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Title Three</h5>
<div class="btn-group" role="group" aria-label="Button group with nested dropdown">
<button type="button" class="btn btn-primary">Button</button>
<div class="btn-group" role="group">
<button id="btnGroupDrop3" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
</button>
<div class="dropdown-menu" aria-labelledby="btnGroupDrop1">
<a class="dropdown-item" href="#">Option 1</a>
<a class="dropdown-item" href="#">Option 2</a>
</div>
</div>
</div>
</div>
<div class="card-footer">
<a href="#" class="badge badge-secondary">another tag</a>
<a href="#" class="badge badge-secondary">last tag</a>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
这是Javascript :
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, .card-footer a.badge");
if (title.innerText.toUpperCase().indexOf(filter) > -1) {
cards[i].style.display = "";
} else {
cards[i].style.display = "none";
}
}
}
它仅基于标签或标题进行过滤,不会同时进行。 请帮忙。
答案 0 :(得分:1)
这是我的解决方案。分别在querySelectorAll
和.card-title
上使用a.badge
,而不是querySelector
,并遍历card_titles
遍历keep_card = true
,如果我们找到了搜索文本。然后,如果该函数仍未找到任何内容,它将以相同的方式搜索badge_titles
。
最后但并非最不重要的一点是,如果keep_card = true
显示卡片,否则将其隐藏。
function myFunction() {
var input, filter, cards, cardContainer, h5, keep_card, card_titles, badge_texts, i, j;
input = document.getElementById("myFilter");
filter = input.value.toUpperCase();
cardContainer = document.getElementById("myItems");
cards = cardContainer.getElementsByClassName("card");
for (i = 0; i < cards.length; i++) {
//We will switch keep_card to true if we find search text in badge or title
keep_card = false;
//querySelectorAll returns all elements of a.badge. querySelector returns only the first element
card_titles = cards[i].querySelectorAll(".card-body h5.card-title");
badge_texts = cards[i].querySelectorAll(".card-footer a.badge");
//You must loop through all card titles.
for(j = 0; j < card_titles.length; j++) {
if (card_titles[j].innerText.toUpperCase().indexOf(filter) > -1) {
//Found search text, now lets switch keep_card on
keep_card = true;
//No need for further looping, we found the card, there we break loop
break;
}
}
if(!keep_card) {
for(j = 0; j < badge_texts.length; j++) {
if (badge_texts[j].innerText.toUpperCase().indexOf(filter) > -1) {
keep_card = true;
break;
}
}
}
if(keep_card) {
cards[i].style.display = "";
} else {
cards[i].style.display = "none";
}
}
}