我有一个从数据库表中获取产品的产品页面,我使用foreach
来拉取每个产品&每个产品显示为一张卡片,并使用类来过滤它们。
问题是复选框过滤器不能正确处理多个值(类),如果我有2个类,过滤器只检测第一类,而不是所有类(过滤器)。
例如,如果我选中"Blue"复选框,我不会看到任何结果,因为JS正在搜索只有一个类("filt-blue")的div,但我需要它显示所有包含"filt-blue"的div以及可能添加的任何其他过滤器。
有关详细信息,请访问**JSFIDDLE**
function change() {
var checkboxes = document.getElementsByClassName('checkbox');
var chekboxInputs = Array.from(checkboxes).map(a => a.querySelector('input'));
var allAreUnselected = chekboxInputs.every(function(elem) {
return !elem.checked;
});
if (allAreUnselected) {
chekboxInputs.forEach(function(input) {
Array.from(document.querySelectorAll("." + input.getAttribute("rel"))).forEach(function(item) {
item.style.display = 'block';
});
});
} else {
chekboxInputs.forEach(function(input) {
Array.from(document.querySelectorAll("." + input.getAttribute("rel"))).forEach(function(item) {
item.style.display = input.checked ? 'block' : 'none';
});
});
}
}
change();
@media(max-width:768px){
.card{
width:100% !important;
margin:12px 6px !important;
}
}
.card {
text-align:left;
border-radius:4px;
margin:24px;
width:320px;
min-height:340px;
transition: all 0.2s;
border:var(--image-select-border);
}
.cards {
display: flex;
flex-wrap: wrap;
justify-content:center;
}
.card-body {
flex: 1 1 auto;
padding:12px;
}
.card-title {
margin-bottom:16px;
padding:12px;
}
@media(max-width:768px){
.card-img-top{
width:240px !important;
}
}
@media(max-width:768px){
.filtbtn{
width:90% !important;
margin-left:5% !important;
float:none !important;
}
}
.filterDiv {
display: none;
}
.show {
display: block;
}
@media(max-width:768px){
#opts{
margin-left:5% !important;
}
}
.optsel{
border-bottom:2px solid #0d6efd;
border-top: none;
border-left: none;
border-right: none;
}
.sidebar {
height:100%;
width:0;
position:fixed;
z-index:1;
top:76px;
right:0;
background-color:#111;
overflow-x:hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidebar a {
padding:8px 12px;
text-decoration: none;
font-size:16px;
color: #818181;
display: block;
transition: 0.3s;
}
.sidebar .closebtn {
position: absolute;
top: 0;
margin-right:12px;
font-size:18px;
color:#222 !important;
background-color:#fff;
width:100%;
}
@media(max-width:768px){
.closebtn{
top:4px !important;
}
}
.openbtn {
font-size: 20px;
cursor: pointer;
background-color: #111;
color: white;
padding: 10px 15px;
border: none;
}
.openbtn:hover {
background-color: #444;
}
#main {
transition: margin-right .5s; /* If you want a transition effect */
padding: 20px;
}
/* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */
@media screen and (max-height: 450px) {
.sidebar {padding-top: 15px;}
.sidebar a {font-size: 22px;}
}
.optbtn{
background-color:#fff;
color: #222;
cursor: pointer;
padding:14px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 16px;
transition: 0.4s;
}
.accordion {
background-color:#111;
color: #fff !important;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.notaccordion {
background-color:#111;
color: #fff !important;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: center;
outline: none;
font-size:18px;
transition: 0.4s;
font-weight:bolder;
}
.active, .accordion:hover {
opacity:0.9;
}
.accordion:after {
content: '\002B';
color: #777;
font-weight: bold;
float: right;
margin-left: 5px;
}
.active:after {
content: "\2212";
}
.filterpanel {
padding:0 18px;
background-color:#fff;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
.checkbox{
color:#222 !important;
padding:12px 12px;
}
.checkbox-button {
cursor: pointer;
}
.checkbox span{
margin-left:12px;
}
.checkbox input[type=checkbox] {
box-sizing: border-box;
padding: 0;
}
.checkbox input {
font-size: 1rem;
line-height: 1.5;
padding: 11px 23px;
border: 1px solid black;
border-radius: 0;
outline: 0;
background-color: transparent;
}
.checkbox-button__input {
opacity: 0;
position: absolute;
}
.checkbox-button__control {
position: relative;
display: inline-block;
width: 20px;
height: 20px;
vertical-align: middle;
background-color: inherit;
color: #017b5f;
border: 2px solid #666;
}
.checkbox-button__input:checked+.checkbox-button__control:after {
content: "";
display: block;
position: absolute;
top: 2px;
left: 2px;
width: 12px;
height: 12px;
background-color:#0d6efd;
}
.checkbox-button__input:checked+.checkbox-button__control {
border-color:black;
border:2px solid black;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous" id="bootstrap-css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous">
<div class="filter">
<div class="checkbox">
<label class="checkbox-button">
<input type="checkbox" class="checkbox-button__input" id="choice1-1" name="choice1" onchange="change()" rel="filt-blue">
<span class="checkbox-button__control"></span>
</label>
<span><b>blue</b></span>
</div>
</div>
<div class="filter">
<div class="checkbox">
<label class="checkbox-button">
<input type="checkbox" class="checkbox-button__input" id="choice1-2" name="choice1" onchange="change()" rel="filt-red">
<span class="checkbox-button__control"></span>
</label>
<span><b>red</b></span>
</div>
</div>
<hr>
<div class="filter">
<div class="checkbox">
<label class="checkbox-button">
<input type="checkbox" class="checkbox-button__input" id="choice1-1a" name="choice2" onchange="change()" rel="filt-long">
<span class="checkbox-button__control"></span>
</label>
<span><b>long</b></span>
</div>
</div>
<div class="filter">
<div class="checkbox">
<label class="checkbox-button">
<input type="checkbox" class="checkbox-button__input" id="choice1-2a" name="choice2" onchange="change()" rel="filt-short">
<span class="checkbox-button__control"></span>
</label>
<span><b>short</b></span>
</div>
</div>
<div class="cards">
<div class="card filt-blue filt-long">
<h6 class="card-title"><b><?php echo $fetch['title'];?></b></h6>
<center><img src="/images/products/<?php echo $fetch['Img'];?>" class="card-img-top" style="width:160px;margin:0 auto;"></center>
<div class="card-body">
<small><?php echo $fetch['detail'];?></small>
<h6><b>Starting from - £<?php echo $fetch['SFprice'];?></b></h6>
</div>
</div>
<div class="card filt-blue filt-short">
<h6 class="card-title"><b><?php echo $fetch['title'];?></b></h6>
<center><img src="/images/products/<?php echo $fetch['Img'];?>" class="card-img-top" style="width:160px;margin:0 auto;"></center>
<div class="card-body">
<small><?php echo $fetch['detail'];?></small>
<h6><b>Starting from - £<?php echo $fetch['SFprice'];?></b></h6>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
2条答案
按热度按时间j5fpnvbx1#
这段代码可以帮助你的过滤器考虑到多个类别。有几种过滤方式。例如,如果你有“long and blue”,你想只显示long and blue吗?或者你也想显示一个“Red Long”。这段代码考虑到了多个过滤器类别,但是是以逻辑OR的方式而不是AND逻辑。
um6iljoc2#
为什么当前代码不起作用?
代码迭代每个
input
,找到所有与input
匹配的卡片,第一个input
是blue
,代码迭代所有卡片,正确显示那些与blue
匹配的卡片,然后继续下一次迭代。red
复选框。没有匹配的牌,所以它们都立即隐藏。所以任何匹配的牌实际上都会显示,然后立即隐藏。好吧,我们该如何解决它?
我的方法是:
注解
onchange="change()"
,并将其替换为JS中的事件处理程序: