我有两个包含独特的过滤器选项的内容类型区域。这些是:
type
tag
我试图利用isotope.js,以实现双重过滤布局,但它总是给最后点击过滤器优先级。
我希望它的运作方式是:
1.如果只选择了一个tag
,则显示具有该tag
的结果
1.如果选择了多个tag
,则显示具有任何这些标签的结果(两个标签不需要同时存在于卡上)
1.如果选择了type
,则仅显示该type
下的结果
1.如果选择了一个type
和一个tag
,则显示所选type
上存在tag
的帖子的结果
1.如果选择了一个type
和多个tags
,则显示属于该类型的具有这些tags
之一的帖子。
1.如果选择了多个type
和一个或多个tag
,则显示其中tag
存在于任一类型上的帖子
例如,使用我下面的演示,这里有一些用例:
1.如果我点击“视频演示和图尔斯”,我应该看到两个视频职位(卡1和3)-作品
1.如果我点击“视频演示和图尔斯”,然后“Ansible”,我应该只看到卡3 -不工作
1.如果我点击“博客&新闻”,我应该看到3卡(卡2,4,5)-作品
1.如果我点击“博客和新闻”,然后点击“Ansible”,我应该会看到卡片4和5
1.如果我点击“博客和新闻”,“Ansible”,然后“自动化”,我应该看到卡2,4和5
然而,在我当前的演示中,尽管控制台日志似乎在正确的行上,但它并没有按照我的意图执行。
document.addEventListener("DOMContentLoaded", function () {
var container = document.querySelector(".grid");
var gridItems = container.querySelectorAll(".grid-item");
const optionLinks = document.querySelectorAll(".rSidebar__options-li");
var iso = new Isotope(container, {
itemSelector: ".resourceCard",
layoutMode: "fitRows",
transitionDuration: "0.5s"
});
var filters = {};
function concatValues(obj) {
var value = [];
for (var prop in obj) {
value.push(obj[prop]);
}
return value.flat().join(", ");
}
function handleFilterClick(event, filters) {
var listItem = event;
var filterGroup = listItem
.closest(".rSidebar__options")
.getAttribute("data-filter-group");
var data_filter = listItem.getAttribute("data-filter");
if (filterGroup === "type") {
filters[filterGroup] = [data_filter];
} else {
if (!filters[filterGroup]) {
filters[filterGroup] = [];
}
if (listItem.classList.contains("selected")) {
filters[filterGroup].push(data_filter);
} else {
filters[filterGroup] = filters[filterGroup].filter(
(tag) => tag !== data_filter
);
}
}
// Combine the type filter with the selected tag filters using an AND relationship
var filterValues = [];
// Handle type filter
if (filters["type"]) {
filterValues.push("." + filters["type"][0]);
}
// Handle tags filter if it's defined
if (filters["tag"]) {
var selectedType = filters["type"][0];
filters["tag"].forEach((tag) => {
filterValues.push("." + selectedType + "." + tag);
});
}
var finalFilter = filterValues.join(", ");
console.log(finalFilter);
iso.arrange({
filter: finalFilter
});
}
optionLinks.forEach(function (optionLink) {
optionLink.addEventListener("click", function (event) {
event.preventDefault();
this.classList.toggle("selected");
handleFilterClick(this, filters);
});
});
});
.post {
padding: 100px;
}
.rSidebar__box {
margin-bottom: 30px;
}
.rSidebar__options {
padding-left: 0;
}
.rSidebar__options-li {
margin-bottom: 17px;
display: flex;
align-items: center;
cursor: pointer;
width: fit-content;
}
.rSidebar__options-li.selected .rSidebar__options-square {
background-color: #185A7D;
}
.rSidebar__options-square {
height: 20px;
width: 20px;
transition: all 0.5s ease;
border: 2px solid #000000;
}
.rSidebar__options-label {
margin-left: 10px;
}
.grid {
display: flex;
flex-wrap: wrap;
margin: -14px 0 0 -14px;
}
.grid-item {
box-sizing: border-box;
width: calc(45% - 14px);
margin: 14px 0 18px 14px;
border: 2px solid black;
padding: 20px;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>
<div class="post">
<div class="container">
<div class="row justify-content-between">
<!-- SIDEBAR -->
<div class="col-3">
<div class="rSidebar">
<!-- tags -->
<div class="rSidebar__box">
<span class="rSidebar__label d-block fw-bold">Filter by tag</span>
<ul class="rSidebar__options button-group" data-filter-group="tag">
<li class="rSidebar__options-li" data-filter="ansible">
<span class="rSidebar__options-square"></span>
<span class="rSidebar__options-label d-block" data-filter="ansible">Ansible</span>
</li>
<li class="rSidebar__options-li" data-filter="automation">
<span class="rSidebar__options-square"></span>
<span class="rSidebar__options-label d-block" data-filter="automation">Automation</span>
</li>
</ul>
</div>
<!-- type -->
<div class="rSidebar__box">
<span class="rSidebar__label d-block fw-bold">Filter by type</span>
<ul class="rSidebar__options button-group" data-filter-group="type">
<li class="rSidebar__options-li" data-filter="blogs-and-news">
<span class="rSidebar__options-square"></span>
<span class="rSidebar__options-label d-block" data-filter="blogs-and-news">Blog & News</span>
</li>
<li class="rSidebar__options-li" data-filter="video-demos-tour">
<span class="rSidebar__options-square"></span>
<span class="rSidebar__options-label d-block" data-filter="video-demos-tours">Video Demos & Tours</span>
</li>
</ul>
</div>
<!-- end -->
</div>
</div>
<!-- END -->
<!-- GRID -->
<div class="col-7">
<div class="grid">
<article class="resourceCard grid-item video-demos-tour automation"><span class="resourceCard__body-title">Card 1<br>Type: Video Demo & Tour<br>Tag: Automation</span></article>
<article class="resourceCard grid-item blogs-and-news"><span class="resourceCard__body-title">Card 2<br>Type: Blog & News<br>Tag: Automation</span></article>
<article class="resourceCard grid-item video-demos-tour automation ansible"><span class="resourceCard__body-title">Card 3<br>Type: Video Demo & Tour<br>Tags: Automation, Ansible</span></article>
<article class="resourceCard grid-item blogs-and-news ansible"><span class="resourceCard__body-title">Card 4<br>Type: Blog & News<br>Tag: Ansible</span></article>
<article class="resourceCard grid-item blogs-and-news ansible"><span class="resourceCard__body-title">Card 5<br>Type: Blog & News<br>Tags: Ansible, Automations</span></article>
</div>
</div>
<!-- END -->
</div>
</div>
</div>
1条答案
按热度按时间hgqdbh6s1#
如果我理解正确的话,你想用OR组合同一组的合并过滤器,用AND组合组之间的过滤器:
在选择器中(如Isotope所使用的),这将是:
你可以通过查看每个组,将每个元素与之前构建的选择器组合来构建它:
如果你更喜欢常规循环,这是这样的:
一些一般提示和建议:
automation
类,不确定这是否是故意的filter
对象,这样就可以避免您以后弄清楚组属性是否已经存在看看更新的片段:
这有意义吗,有帮助吗?