如何创建允许用户在 JavaScript 中多次过滤的功能?
How can I create functionality that allows the user to filter multiple times in JavaScript?
我一直在开发一个网站,该网站显示学生为他们的高级项目完成的项目。我希望能够按项目类别进行排序,以方便用户使用。我在其中添加了该功能,并且一切正常。然后我决定,因为我的网站上会有多年的高级项目,我也想按年份过滤。但是,多年来我不能只添加更多按钮。例如,如果我按 2022 年的 class 进行筛选,我将无法按 2022 年 class 内的类别进行筛选。更具体地说,当我按 2022 时,它会显示所有学生class。然后,例如,如果我按 Creative Project,它会返回到显示每一个 Creative Project 而不是从 2022 年的 class 开始。我最初的想法是制作另一个功能 div毕业年份按钮。然而,这并没有改变任何东西。这是我的 JavaScript 代码:
function filterProject(value){
let buttons = document.querySelectorAll(".button-value");
buttons.forEach((button) => {
if(value.toUpperCase() == button.innerText.toUpperCase()){
button.classList.add("active");
}else{
button.classList.remove("active");
}
});
let elements = document.querySelectorAll(".card");
elements.forEach((element) => {
if(value == "all"){
element.classList.remove("hide");
}
else{
//having a space messes it up, make it _
if(element.classList.contains(value.replace(" ", "_"))){
element.classList.remove("hide");
}
else{
element.classList.add("hide");
}
}
});
}
function filterProject2(value){
let buttons = document.querySelectorAll(".grad-button");
buttons.forEach((button) => {
if(value.toUpperCase() == button.innerText.toUpperCase()){
button.classList.add("active");
}else{
button.classList.remove("active");
}
});
let elements = document.querySelectorAll(".card");
elements.forEach((element) => {
if(value == "All Years"){
element.classList.remove("hide");
}
else{
//having a space messes it up, make it _
if(element.classList.contains(value.replace(" ", "_"))){
element.classList.remove("hide");
}
else{
element.classList.add("hide");
}
}
});
}
这里还有相关的 HTML 代码:
<div id ="buttons">
<button class = "button-value" onclick="filterProject('all')">All</button>
<button class = "button-value" onclick="filterProject('Creative Project')">Creative Project</button>
<button class = "button-value" onclick="filterProject('Developing Voice')">Developing Voice</button>
<button class = "button-value" onclick="filterProject('Interdisciplinary Fusion')">Interdisciplinary Fusion</button>
<button class = "button-value" onclick="filterProject('Personal Writing')">Personal Writing</button>
<button class = "button-value" onclick="filterProject('Curriculum Designer')">Curriculum Designer</button>
<button class = "button-value" onclick="filterProject('Internship')">Internship</button>
</div>
<div id ="gradbuttons">
<button class = "grad-button" onclick="filterProject2('All Years')">All Years</button>
<button class = "grad-button" onclick="filterProject2('2021')">2021</button>
<button class = "grad-button" onclick="filterProject2('2022')">2022</button>
</div>
我知道我可以添加另一个页面,按毕业年份分隔项目并且每年都有不同的按钮,但我想使用 JavaScript 并使网站更干净。任何建议都会有所帮助。谢谢!
我会使用对象 var filters = { "category": "", "year": "" };
作为状态变量来存储当前的过滤器选项。由于您在两个过滤器函数中执行类似的逻辑,我会将它们组合成一个函数,该函数接受一个附加参数 filterType
,即 "category"
或 "year"
。然后在您的过滤逻辑中,您可以为适当的过滤器类型更新当前过滤器,并确保满足 filters
中的每个条件。
您可以使用两个不同的 class 来代替使用唯一的 class 来隐藏元素,例如 category-hidden
和 year-hidden
。
内部类别过滤器:
button.classList.add('category-hidden')
内部年份过滤器:
button.classList.add('year-hidden')
然后,在您的 css 中,您隐藏具有两个 class 的元素。
<style>
.category-hidden .year-hidden {
display: none;
}
</style>
编辑
我刚刚意识到,如果您 select 只有一个过滤器,这种方法将不起作用。因此,您需要将 classes 添加到元素的容器中,以指示哪些过滤器当前处于活动状态。例如,如果您激活年份过滤器,请添加 class year-filter-active
.
<div id="container" class="year-filter-active">
...
elements
...
</div>
并在您的 css 中加入以下规则:
<style>
div.year-filter-active .year-hidden, div.category-filter-active .category-hidden {
display: none;
}
</style>
我一直在开发一个网站,该网站显示学生为他们的高级项目完成的项目。我希望能够按项目类别进行排序,以方便用户使用。我在其中添加了该功能,并且一切正常。然后我决定,因为我的网站上会有多年的高级项目,我也想按年份过滤。但是,多年来我不能只添加更多按钮。例如,如果我按 2022 年的 class 进行筛选,我将无法按 2022 年 class 内的类别进行筛选。更具体地说,当我按 2022 时,它会显示所有学生class。然后,例如,如果我按 Creative Project,它会返回到显示每一个 Creative Project 而不是从 2022 年的 class 开始。我最初的想法是制作另一个功能 div毕业年份按钮。然而,这并没有改变任何东西。这是我的 JavaScript 代码:
function filterProject(value){
let buttons = document.querySelectorAll(".button-value");
buttons.forEach((button) => {
if(value.toUpperCase() == button.innerText.toUpperCase()){
button.classList.add("active");
}else{
button.classList.remove("active");
}
});
let elements = document.querySelectorAll(".card");
elements.forEach((element) => {
if(value == "all"){
element.classList.remove("hide");
}
else{
//having a space messes it up, make it _
if(element.classList.contains(value.replace(" ", "_"))){
element.classList.remove("hide");
}
else{
element.classList.add("hide");
}
}
});
}
function filterProject2(value){
let buttons = document.querySelectorAll(".grad-button");
buttons.forEach((button) => {
if(value.toUpperCase() == button.innerText.toUpperCase()){
button.classList.add("active");
}else{
button.classList.remove("active");
}
});
let elements = document.querySelectorAll(".card");
elements.forEach((element) => {
if(value == "All Years"){
element.classList.remove("hide");
}
else{
//having a space messes it up, make it _
if(element.classList.contains(value.replace(" ", "_"))){
element.classList.remove("hide");
}
else{
element.classList.add("hide");
}
}
});
}
这里还有相关的 HTML 代码:
<div id ="buttons">
<button class = "button-value" onclick="filterProject('all')">All</button>
<button class = "button-value" onclick="filterProject('Creative Project')">Creative Project</button>
<button class = "button-value" onclick="filterProject('Developing Voice')">Developing Voice</button>
<button class = "button-value" onclick="filterProject('Interdisciplinary Fusion')">Interdisciplinary Fusion</button>
<button class = "button-value" onclick="filterProject('Personal Writing')">Personal Writing</button>
<button class = "button-value" onclick="filterProject('Curriculum Designer')">Curriculum Designer</button>
<button class = "button-value" onclick="filterProject('Internship')">Internship</button>
</div>
<div id ="gradbuttons">
<button class = "grad-button" onclick="filterProject2('All Years')">All Years</button>
<button class = "grad-button" onclick="filterProject2('2021')">2021</button>
<button class = "grad-button" onclick="filterProject2('2022')">2022</button>
</div>
我知道我可以添加另一个页面,按毕业年份分隔项目并且每年都有不同的按钮,但我想使用 JavaScript 并使网站更干净。任何建议都会有所帮助。谢谢!
我会使用对象 var filters = { "category": "", "year": "" };
作为状态变量来存储当前的过滤器选项。由于您在两个过滤器函数中执行类似的逻辑,我会将它们组合成一个函数,该函数接受一个附加参数 filterType
,即 "category"
或 "year"
。然后在您的过滤逻辑中,您可以为适当的过滤器类型更新当前过滤器,并确保满足 filters
中的每个条件。
您可以使用两个不同的 class 来代替使用唯一的 class 来隐藏元素,例如 category-hidden
和 year-hidden
。
内部类别过滤器:
button.classList.add('category-hidden')
内部年份过滤器:
button.classList.add('year-hidden')
然后,在您的 css 中,您隐藏具有两个 class 的元素。
<style>
.category-hidden .year-hidden {
display: none;
}
</style>
编辑
我刚刚意识到,如果您 select 只有一个过滤器,这种方法将不起作用。因此,您需要将 classes 添加到元素的容器中,以指示哪些过滤器当前处于活动状态。例如,如果您激活年份过滤器,请添加 class year-filter-active
.
<div id="container" class="year-filter-active">
...
elements
...
</div>
并在您的 css 中加入以下规则:
<style>
div.year-filter-active .year-hidden, div.category-filter-active .category-hidden {
display: none;
}
</style>