我必须创建一个列出19门课程的页面。我想为其添加过滤功能,以允许访问者按不同特征(作业功能,日期,持续时间,位置,产品等)过滤课程。
我遇到了这个previous question on StackOverflow,它几乎可以解决我的问题。但是,该解决方案只有3套复选框,而我需要8套。
我在JSFiddle上有一些代码,可以过滤前三个类别,但超出的范围则无法过滤。
var byProperty = [],
byColor = [],
byLocation = [];
$("input[name=cat1]").on("change", function() {
if (this.checked) byProperty.push("[data-category~='" + $(this).attr("value") + "']");
else removeA(byProperty, "[data-category~='" + $(this).attr("value") + "']");
});
$("input[name=cat2]").on("change", function() {
if (this.checked) byColor.push("[data-category~='" + $(this).attr("value") + "']");
else removeA(byColor, "[data-category~='" + $(this).attr("value") + "']");
});
$("input[name=cat3]").on("change", function() {
if (this.checked) byLocation.push("[data-category~='" + $(this).attr("value") + "']");
else removeA(byLocation, "[data-category~='" + $(this).attr("value") + "']");
});
$("input").on("change", function() {
var str = "Include items \n";
var selector = '',
cselector = '',
nselector = '';
var $lis = $('.courses > div'),
$checked = $('input:checked');
if ($checked.length) {
if (byProperty.length) {
if (str == "Include items \n") {
str += " " + "with (" + byProperty.join(',') + ")\n";
$($('input[name=cat1]:checked')).each(function(index, byProperty) {
if (selector === '') {
selector += "[data-category~='" + byProperty.id + "']";
} else {
selector += ",[data-category~='" + byProperty.id + "']";
}
});
} else {
str += " AND " + "with (" + byProperty.join(' OR ') + ")\n";
$($('input[name=cat2]:checked')).each(function(index, byProperty) {
selector += "[data-category~='" + byProperty.id + "']";
});
}
}
if (byColor.length) {
if (str == "Include items \n") {
str += " " + "with (" + byColor.join(' OR ') + ")\n";
$($('input[name=cat2]:checked')).each(function(index, byColor) {
if (selector === '') {
selector += "[data-category~='" + byColor.id + "']";
} else {
selector += ",[data-category~='" + byColor.id + "']";
}
});
} else {
str += " AND " + "with (" + byColor.join(' OR ') + ")\n";
$($('input[name=cat2]:checked')).each(function(index, byColor) {
if (cselector === '') {
cselector += "[data-category~='" + byColor.id + "']";
} else {
cselector += ",[data-category~='" + byColor.id + "']";
}
});
}
}
if (byLocation.length) {
if (str == "Include items \n") {
str += " " + "with (" + byLocation.join(' OR ') + ")\n";
$($('input[name=cat3]:checked')).each(function(index, byLocation) {
if (selector === '') {
selector += "[data-category~='" + byLocation.id + "']";
} else {
selector += ",[data-category~='" + byLocation.id + "']";
}
});
} else {
str += " AND " + "with (" + byLocation.join(' OR ') + ")\n";
$($('input[name=cat3]:checked')).each(function(index, byLocation) {
if (nselector === '') {
nselector += "[data-category~='" + byLocation.id + "']";
} else {
nselector += ",[data-category~='" + byLocation.id + "']";
}
});
}
}
$lis.hide();
console.log(selector);
console.log(cselector);
console.log(nselector);
if (cselector === '' && nselector === '') {
$('.courses > div').filter(selector).show();
} else if (cselector === '') {
$('.courses > div').filter(selector).filter(nselector).show();
} else if (nselector === '') {
$('.courses > div').filter(selector).filter(cselector).show();
} else {
$('.courses > div').filter(selector).filter(cselector).filter(nselector).show();
}
} else {
$lis.show();
}
$("#result").html(str);
});
function removeA(arr) {
var what, a = arguments,
L = a.length,
ax;
while (L > 1 && arr.length) {
what = a[--L];
while ((ax = arr.indexOf(what)) !== -1) {
arr.splice(ax, 1);
}
}
return arr;
}
body {
font-family: 'Arial';
color: #646464;
}
.filters-wrap {
float: left;
width: 20%;
margin: 0 5% 0 0;
padding: 0;
position: relative;
}
.filters {
float: left;
width: 50%;
}
.filters div {
float: left;
width: 90%;
height: 68px;
line-height: 68px;
padding: 0 5%;
background: #eee;
margin: 0 0 1px;
position: relative;
}
<div class="filters-wrap">
<h3>Category 1</h3>
<form>
<label><input type="checkbox" name="cat1" value="1-a" id="1-a" />1-A</label><br>
<label><input type="checkbox" name="cat1" value="1-b" id="1-b" />1-B</label><br>
<label><input type="checkbox" name="cat1" value="1-c" id="1-c" />1-C</label><br>
</form>
<h3>Category 2</h3>
<form>
<label><input type="checkbox" name="cat2" value="2-a" id="2-a" />2-A</label><br>
<label><input type="checkbox" name="cat2" value="2-b" id="2-b" />2-B</label><br>
<label><input type="checkbox" name="cat2" value="2-c" id="2-c" />2-C</label><br>
</form>
<h3>Category 3</h3>
<form>
<label><input type="checkbox" name="cat3" value="3-a" id="3-a" />3-A</label><br>
<label><input type="checkbox" name="cat3" value="3-b" id="3-b" />3-B</label><br>
<label><input type="checkbox" name="cat3" value="3-c" id="3-c" />3-C</label><br>
</form>
<h3>Category 4</h3>
<form>
<label><input type="checkbox" name="cat4" value="4-a" id="4-a" />4-A</label><br>
<label><input type="checkbox" name="cat4" value="4-b" id="4-b" />4-B</label><br>
<label><input type="checkbox" name="cat4" value="4-c" id="4-c" />4-C</label><br>
</form>
<h3>Category 5</h3>
<form>
<label><input type="checkbox" name="cat5" value="5-a" id="5-a" />5-A</label><br>
<label><input type="checkbox" name="cat5" value="5-b" id="5-b" />5-B</label><br>
<label><input type="checkbox" name="cat5" value="5-c" id="5-c" />5-C</label><br>
</form>
<h3>Category 6</h3>
<form>
<label><input type="checkbox" name="cat6" value="6-a" id="6-a" />6-A</label><br>
<label><input type="checkbox" name="cat6" value="6-b" id="6-b" />6-B</label><br>
<label><input type="checkbox" name="cat6" value="6-c" id="6-c" />6-C</label><br>
</form>
<h3>Category 7</h3>
<form>
<label><input type="checkbox" name="cat7" value="7-a" id="7-a" />7-A</label><br>
<label><input type="checkbox" name="cat7" value="7-b" id="7-b" />7-A</label><br>
<label><input type="checkbox" name="cat7" value="7-c" id="7-c" />7-A</label><br>
</form>
<h3>Category 8</h3>
<form>
<label><input type="checkbox" name="cat8" value="8-a" id="8-a" />8-A</label><br>
<label><input type="checkbox" name="cat8" value="8-b" id="8-b" />8-B</label><br>
<label><input type="checkbox" name="cat8" value="8-c" id="8-c" />8-C</label><br>
</form>
</div>
<div class="courses">
<div class="course" data-id="course01" data-category="1-a 2-b 4-c">Course 1 [cat 1A, 2B, 4C]</div>
<div class="course" data-id="course02" data-category="3-c 6-b 7-c 8-a">Course 2 [cat 3C, 6BB, 7C, 8A]</div>
<div class="course" data-id="course03" data-category="3-a 6-b 8-c">Course 3 [cat 3A, 6B, 8C]</div>
<div class="course" data-id="course04" data-category="5-c 6-b">Course 4 [cat 5C, 6B]</div>
</div>
如何编辑包含其余类别(4-8)的代码?
谢谢!
答案 0 :(得分:0)
也许我错过了一些重要的事情,但是除了对眼前的情况过于具体之外,原始代码有点太复杂了,并不必要地重复了代码(例如,它为每个类别和选择器定义了一个特定的数组)...这让我写了些不同的东西。
可以通过简化数组来简化整个过程,使它们更通用,因为可以使用数组数组来保存类别值,而不是使用单独变量中的数组。这样,如果要在过滤中添加/删除类别,则只需指定新的类别数,而不是为每个类别添加/删除数十行代码。
此外,如果您没有创建选择器(可能会很庞大),而只是更改了一点HTML并使用了不同的数据属性(每个类别有一个数据属性,而不是一个大数据属性)包含所有这些)。 注意:在编写答案时要考虑一下,此步骤可以是可选的。
这是我所做的更改的列表:
.hidden
,隐藏了添加元素的元素。有了这些更改,(注释的)代码如下所示:
// constant: number of categories (this could be calculated if properly designed)
const NUM_CATEGORIES = 8;
// every time an option is clicked
$("input[type='checkbox']").on("click", function() {
// generate an array with the checked options per category
let selected = new Array(NUM_CATEGORIES);
// for each category
for (let x = 0; x < NUM_CATEGORIES; x++) {
// generate an array
selected[x] = [];
// populate it with the values of the checked options
$("input[name=cat" + (x+1) + "]:checked").each(function() {
selected[x].push($(this).val());
});
}
// for each course
$(".course").each(function() {
// by default it is going to be displayed
let show = true;
// we check all the categories
for (let x = 0; x < NUM_CATEGORIES; x++) {
// if they have a checked value
if (selected[x].length) {
// if the course has a value for that category
if (this.dataset["cat-" + (x+1)]) {
// convert the value into an array (in case there are multiple)
var catValues = this.dataset["cat-" + (x+1)].split(",");
// check if any of the values of the array is a selected category
show = catValues.some(val => selected[x].indexOf(val) >= 0);
// if not, hide and no need to keep checking
if (!show) break;
}
// if the course does not have a value for that checked category
else {
// hide and no need to keep checking
show = false;
break;
}
}
}
// hide or show depending on if it has fulfilled the condition
$(this).toggleClass("hidden", !show);
});
});
body {
font-family: 'Arial';
color: #646464;
}
.filters-wrap {
float: left;
width: 20%;
margin: 0 5% 0 0;
padding: 0;
position: relative;
}
.filters {
float: left;
width: 50%;
}
.filters div {
float: left;
width: 90%;
height: 68px;
line-height: 68px;
padding: 0 5%;
background: #eee;
margin: 0 0 1px;
position: relative;
}
.courses {
position: fixed;
right: 10px;
top: 50px;
}
.course.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="filters-wrap">
<h3>Category 1</h3>
<form>
<label><input type="checkbox" name="cat1" value="a" id="1-a" />1-A</label><br>
<label><input type="checkbox" name="cat1" value="b" id="1-b" />1-B</label><br>
<label><input type="checkbox" name="cat1" value="c" id="1-c" />1-C</label><br>
</form>
<h3>Category 2</h3>
<form>
<label><input type="checkbox" name="cat2" value="a" id="2-a" />2-A</label><br>
<label><input type="checkbox" name="cat2" value="b" id="2-b" />2-B</label><br>
<label><input type="checkbox" name="cat2" value="c" id="2-c" />2-C</label><br>
</form>
<h3>Category 3</h3>
<form>
<label><input type="checkbox" name="cat3" value="a" id="3-a" />3-A</label><br>
<label><input type="checkbox" name="cat3" value="b" id="3-b" />3-B</label><br>
<label><input type="checkbox" name="cat3" value="c" id="3-c" />3-C</label><br>
</form>
<h3>Category 4</h3>
<form>
<label><input type="checkbox" name="cat4" value="a" id="4-a" />4-A</label><br>
<label><input type="checkbox" name="cat4" value="b" id="4-b" />4-B</label><br>
<label><input type="checkbox" name="cat4" value="c" id="4-c" />4-C</label><br>
</form>
<h3>Category 5</h3>
<form>
<label><input type="checkbox" name="cat5" value="a" id="5-a" />5-A</label><br>
<label><input type="checkbox" name="cat5" value="b" id="5-b" />5-B</label><br>
<label><input type="checkbox" name="cat5" value="c" id="5-c" />5-C</label><br>
</form>
<h3>Category 6</h3>
<form>
<label><input type="checkbox" name="cat6" value="a" id="6-a" />6-A</label><br>
<label><input type="checkbox" name="cat6" value="b" id="6-b" />6-B</label><br>
<label><input type="checkbox" name="cat6" value="c" id="6-c" />6-C</label><br>
</form>
<h3>Category 7</h3>
<form>
<label><input type="checkbox" name="cat7" value="a" id="7-a" />7-A</label><br>
<label><input type="checkbox" name="cat7" value="b" id="7-b" />7-A</label><br>
<label><input type="checkbox" name="cat7" value="c" id="7-c" />7-A</label><br>
</form>
<h3>Category 8</h3>
<form>
<label><input type="checkbox" name="cat8" value="a" id="8-a" />8-A</label><br>
<label><input type="checkbox" name="cat8" value="b" id="8-b" />8-B</label><br>
<label><input type="checkbox" name="cat8" value="c" id="8-c" />8-C</label><br>
</form>
</div>
<div class="courses">
<div class="course" data-id="course01" data-cat-1="a" data-cat-2="b" data-cat-4="c">Course 1 [cat 1A, 2B, 4C]</div>
<div class="course" data-id="course02" data-cat-3="c" data-cat-6="b,c" data-cat-7="c" data-cat-8="a">Course 2 [cat 3C, 6BC, 7C, 8A]</div>
<div class="course" data-id="course03" data-cat-3="a" data-cat-6="b" data-cat-8="c">Course 3 [cat 3A, 6B, 8C]</div>
<div class="course" data-id="course04" data-cat-5="c" data-cat-6="b">Course 4 [cat 5C, 6B]</div>
</div>