如何创建允许用户在 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-hiddenyear-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>