使用JS进行多类别过滤?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用JS进行多类别过滤?相关的知识,希望对你有一定的参考价值。

我目前正在做一个网站,可以直观地显示我看过的所有电影。一个电影列表,如果你愿意。我想出了如何使用JS来过滤基于按钮按下的列表,然而,它只过滤1按钮的时间。我希望列表能根据多个按钮进行过滤。

比如说 "全部 竣工 电影 评分 3和行动 类型*".

或:"所有 竣工观看 电影"

我从来没有学过JS(虽然我打算最终要学),所以我对如何做这件事有点迷茫。

这是我现在的代码。

filterSelection("all")
function filterSelection(c) {
    var eles = document.getElementsByClassName("flex-card");
    for(var i=0; i < eles.length; i++) {
        if (c === "all" || eles[i].classList.contains(c)) {
            eles[i].classList.remove("displayNone");
    		} 
        else {
    		    eles[i].classList.add("displayNone");
        }
    }
}
.card:hover .overlay {
    display: none;
}

.btn:hover {
    background-color: hsl(14,80%,70%);
}

.displayNone {
    display: none;
}

.yellow {
    color: hsl(14,80%,70%);
}

.heading {
    color: white;
}

.button-container {
    margin: 0px 0px 12px;
    text-align: center;
    padding-bottom: 12px;
}

.btn {
    color: hsl(14,80%,30%);
    background-color: hsl(43,83%,55%);
    border: 1px solid rgba(0, 0, 0, 0.94);
    border-radius: 10px;
    text-align: center;
    font-weight: 600;
    font-size: 10px;
    line-height: 20px;
    width: 80px;
    margin: 5px 0px 5px 5px;
    padding: 0px 12px;
}

.flex-container {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    padding-left: 15%;
    padding-right: 15%;
}

/* I am using a 7:10 aspect ratio (width:height) */
.flex-card {
    position: relative;
    height: 265px;
    width: 185px;
    perspective: 1000px;
    margin-right: 1rem;
    margin-bottom: 1rem;
}

.a {
}

.card {
    position: relative;
    width: 100%;
    height: 100%;
    transition: transform 0.6s  0s;
    transform-style: preserve-3d;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
}

.image {
    object-fit: cover;
    width: 100%;
    height: 100%;
}

.overlay {
    position: absolute;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.7);
    width: 100%;
    transition: .1s ease;
}

.title {
    text-align: center;
    color: white;
    font-size: 14px;
    font-weight: 600;
    margin: 8px;
}

.subtitle {
    margin: 8px;
    font-size: 12px;
    font-weight: 600;
    text-align: center;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="description" content="">
        <meta name="author" content="">
        <title>New page</title>
        <link href="css/new.css" rel="stylesheet" type="text/css">
    </head>
    <body style="background-color: rgb(19,23,29);">
        <div>
            <h1 style="text-align: center;" class="heading">Movie List</h1>
            <div class="button-container" data-pg-name="Buttons">
                <button class="btn" onclick="filterSelection('all')">All</button>
                <button class="btn" onclick="filterSelection('watching')">Watching</button>
                <button class="btn" onclick="filterSelection('planned')">Planned</button>
                <button class="btn" onclick="filterSelection('completed')">Completed</button>
                <button class="btn" onclick="filterSelection('dropped')">Dropped</button>
                <br>
                <button class="btn" onclick="filterSelection('five')">5</button>
                <button class="btn" onclick="filterSelection('four')">4</button>
                <button class="btn" onclick="filterSelection('three')">3</button>
                <button class="btn" onclick="filterSelection('two')">2</button>
                <button class="btn" onclick="filterSelection('one')">1</button>
                <br>
                <button class="btn" onclick="filterSelection('action')">Action</button>
                <button class="btn" onclick="filterSelection('horror')">Horror</button>
                <button class="btn" onclick="filterSelection('romance')">Romance</button>
                <button class="btn" onclick="filterSelection('etc')">etc.</button>
                <button class="btn" onclick="filterSelection('etc')">etc.</button>
            </div>
        </div>
        <div class="flex-container">
            <div class="watching five flex-card">
                <a href="#">
                    <div class="card">
                        <img src="https://via.placeholder.com/300" class="image">
                        <div class="overlay">
                            <p class="title">Title</p>
                            <p class="subtitle yellow">Studio</p>
                        </div>
                    </div>
                </a>
            </div>
            <div class="planned three flex-card">
                <a href="#">
                    <div class="card">
                        <img src="https://via.placeholder.com/300" class="image">
                        <div class="overlay">
                            <p class="title">Title</p>
                            <p class="subtitle yellow">Studio</p>
                        </div>
                    </div>
                </a>
            </div>
            <div class="completed two flex-card">
                <a href="#">
                    <div class="card">
                        <img src="https://via.placeholder.com/300" class="image">
                        <div class="overlay">
                            <p class="title">Title</p>
                            <p class="subtitle yellow">Studio</p>
                        </div>
                    </div>
                </a>
            </div>
        </div>
    </body>
</html>

也在 jsfidle

答案

可以将所有点击过的选择器存储在一个数组中,并根据整个数组的状态来渲染卡片,而不仅仅是最后点击的按钮。快速和肮脏的例子可以是这样的。

const allCards = document.querySelectorAll(".flex-card");
var displayAll = true  // special value for displaying all - default true
var activeCards = []  // array holding all selected values

function toggleSelector(c) {
    if (c === 'all') {
    displayAll = !displayAll
    activeCards = []  // optional
    return
  }

  displayAll = false
  if (activeCards.includes(c)) {
    activeCards = activeCards.filter(card => card !== c)
  } else {
    activeCards.push(c)
  }
}

// quick dirty way to render cards
function renderCards() {
  if (displayAll) {
    allCards.forEach(card => showCard(card))
    return
  }

  allCards.forEach(card => hideCard(card))  
  
  for (let card of allCards) {
    for (let cardClass of card.classList) {
      if (activeCards.includes(cardClass)) {
      	showCard(card)
        break;
      }
    }
  }
}

// on each click toggle clicked selector and re-render cards
function filterSelection(c) {
  toggleSelector(c)
  renderCards()
}

function showCard(card) {
  card.classList.remove("displayNone");	
}

function hideCard(card) {
  card.classList.add("displayNone");
}

renderCards()
.card:hover .overlay {
    display: none;
}

.btn:hover {
    background-color: hsl(14,80%,70%);
}

.displayNone {
    display: none;
}

.yellow {
    color: hsl(14,80%,70%);
}

.heading {
    color: white;
}

.button-container {
    margin: 0px 0px 12px;
    text-align: center;
    padding-bottom: 12px;
}

.btn {
    color: hsl(14,80%,30%);
    background-color: hsl(43,83%,55%);
    border: 1px solid rgba(0, 0, 0, 0.94);
    border-radius: 10px;
    text-align: center;
    font-weight: 600;
    font-size: 10px;
    line-height: 20px;
    width: 80px;
    margin: 5px 0px 5px 5px;
    padding: 0px 12px;
}

.flex-container {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    padding-left: 15%;
    padding-right: 15%;
}

/* I am using a 7:10 aspect ratio (width:height) */
.flex-card {
    position: relative;
    height: 265px;
    width: 185px;
    perspective: 1000px;
    margin-right: 1rem;
    margin-bottom: 1rem;
}

.a {
}

.card {
    position: relative;
    width: 100%;
    height: 100%;
    transition: transform 0.6s  0s;
    transform-style: preserve-3d;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
}

.image {
    object-fit: cover;
    width: 100%;
    height: 100%;
}

.overlay {
    position: absolute;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.7);
    width: 100%;
    transition: .1s ease;
}

.title {
    text-align: center;
    color: white;
    font-size: 14px;
    font-weight: 600;
    margin: 8px;
}

.subtitle {
    margin: 8px;
    font-size: 12px;
    font-weight: 600;
    text-align: center;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="description" content="">
        <meta name="author" content="">
        <title>New page</title>
        <link href="css/new.css" rel="stylesheet" type="text/css">
    </head>
    <body style="background-color: rgb(19,23,29);">
        <div>
            <h1 style="text-align: center;" class="heading">Movie List</h1>
            <div class="button-container" data-pg-name="Buttons">
                <button class="btn" onclick="filterSelection('all')">All</button>
                <button class="btn" onclick="filterSelection('watching')">Watching</button>
                <button class="btn" onclick="filterSelection('planned')">Planned</button>
                <button class="btn" onclick="filterSelection('completed')">Completed</button>
                <button class="btn" onclick="filterSelection('dropped')">Dropped</button>
                <br>
                <button class="btn" onclick="filterSelection('five')">5</button>
                <button class="btn" onclick="filterSelection('four')">4</button>
                <button class="btn" onclick="filterSelection('three')">3</button>
                <button class="btn" onclick="filterSelection('two')">2</button>
                <button class="btn" onclick="filterSelection('one')">1</button>
                <br>
                <button class="btn" onclick="filterSelection('action')">Action</button>
                <button class="btn" onclick="filterSelection('horror')">Horror</button>
                <button class="btn" onclick="filterSelection('romance')">Romance</button>
                <button class="btn" onclick="filterSelection('etc')">etc.</button>
                <button class="btn" onclick="filterSelection('etc')">etc.</button>
            </div>
        </div>
        <div class="flex-container">
            <div class="watching five flex-card displayNone">
                <a href="#">
                    <div class="card">
                        <img src="https://via.placeholder.com/300" class="image">
                        <div class="overlay">
                            <p class="title">Title</p>
                            <p class="subtitle yellow">Studio</p>
                        </div>
                    </div>
                </a>
            </div>
            <div class="planned three flex-card displayNone action">
                <a href="#">
                    <div class="card">
                        <img src="https://via.placeholder.com/300" class="image">
                        <div class="overlay">
                            <p class="title">Title</p>
                            <p class="subtitle yellow">Studio</p>
                        </div>
                    </div>
                </a>
            </div>
            <div class="completed two flex-card displayNone action">
                <a href="#">
                    <div class="card">
                        <img src="https://via.placeholder.com/300" class="image">
                        <div class="overlay">
                            <p class="title">Title</p>
                            <p class="subtitle yellow">Studio</p>
                        </div>
                    </div>
                </a>
            </div>
        </div>
    </body>
</html>

以上是关于使用JS进行多类别过滤?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5 / Eloquent - 对属于多的关系进行查询过滤

php 类别过滤器分类多过滤器多过滤器多过滤器

从类别中加载所有产品并按 Magento 中选定的多选属性进行过滤

php 多类别过滤器

多对多关系过滤器

为什么我不能在此片段中生成唯一对象数组?