javascript - 如何使用 HTML 按钮实现简单的递归过滤器
问题描述
我想使用简单的 HTML 按钮/javascript 添加递归过滤器。到目前为止,我只能添加一级过滤器。我想要做的是 - 允许用户分两个阶段选择过滤器。例如,用户应该能够过滤经验范围“10+”,然后进一步过滤下一阶段,例如“操作”。所以这种方式只显示适合 10+ 经验和操作的配置文件。
我已经能够为一个阶段添加过滤器和逻辑。也就是说,代码在经验范围(5-8、8-10、10+)上工作和过滤,但无法实现过滤器的第二阶段(IT、运营等)
filterSelection("all")
function filterSelection(c) {
var x, i;
x = document.getElementsByClassName("column");
if (c == "all") c = "";
for (i = 0; i < x.length; i++) {
w3RemoveClass(x[i], "show");
if (x[i].className.indexOf(c) > -1) w3AddClass(x[i], "show");
}
}
function w3AddClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {
element.className += " " + arr2[i];
}
}
}
function w3RemoveClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
}
// Add active class to the current button (highlight it)
var btnContainer = document.getElementById("myBtnContainer");
var btns = btnContainer.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
var current = document.getElementsByClassName("active");
current[0].className = current[0].className.replace(" active", "");
this.className += " active";
});
}
* {
box-sizing: border-box;
}
body {
background-color: #f1f1f1;
padding: 20px;
font-family: Arial;
}
/* Center website */
.main {
max-width: 1000px;
margin: auto;
}
h1 {
font-size: 50px;
word-break: break-all;
}
.row {
margin: 8px -16px;
}
/* Add padding BETWEEN each column */
.row,
.row>.column {
padding: 8px;
}
/* Create four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
display: none;
/* Hide all elements by default */
}
/* Clear floats after rows */
.row:after {
content: "";
display: table;
clear: both;
}
/* Content */
.content {
background-color: white;
padding: 10px;
}
/* The "show" class is added to the filtered elements */
.show {
display: block;
}
/* Style the buttons */
.btn {
border: none;
outline: none;
padding: 12px 16px;
background-color: white;
cursor: pointer;
}
.btn:hover {
background-color: #ddd;
}
.btn.active {
background-color: #666;
color: white;
}
/* Responsive layout - makes a two column-layout instead of four columns */
@media screen and (max-width: 900px) {
.column {
width: 50%;
}
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
@media screen and (max-width: 600px) {
.column {
width: 100%;
}
}
<!-- MAIN (Center website) -->
<div class="main">
<div id="myBtnContainer">
<button class="btn active" onclick="filterSelection('all')"> Show all</button>
<button class="btn" onclick="filterSelection('5-8')"> 5-8</button>
<button class="btn" onclick="filterSelection('8-10')"> 8-10</button>
<button class="btn" onclick="filterSelection('10+')"> 10+</button>
</div>
<div id="myBtnContainer">
<button class="btn" onclick="filterSelection('Operations')"> Operations</button>
<button class="btn" onclick="filterSelection('Manufacturing')"> Manufacturing</button>
</div>
<!-- Portfolio Gallery Grid -->
<div class="row">
<div class="column 8-10">
<div class="content">
<a href="https://xxx" target="_blank">
<img src="https:xxx" alt="Bagish" style="width:100%" ;height:auto;>
<h4>abc</h4>
<p>8+ Experience in Oil&Gas, Manufacturing</p>
</div>
</div>
<div class="column 10+">
<div class="content">
<a href="https://xxx">
<img src="xxx" alt="def" style="width:100%" ;height:auto;>
<h4>def</h4>
<p>10+ Experience in Oil&Gas, Manufacturing</p>
</div>
</div>
<div class="column 10+">
<div class="content">
<a href="https://abc">
<img src="abc" ;height:auto;>
<h4>ghi</h4>
<p>13+ Experience in IT Program Management</p>
</div>
</div>
<!-- END GRID -->
</div>
<!-- END MAIN -->
</div>
请帮我为 IT/运营等添加另一个级别的过滤器。
解决方案
进行了一些调整和简化,但假设可以按您的意愿工作;-)
如果您满意,请记住按接受按钮(正在投票中)。
var filtersList = {};
filterSelection(document.getElementsByName("myBtnContainer")[0].children[0]);
function renameAll(i) {
return i.replace('Show all', 'all');
}
function filterSelection(current) {
var x, i;
var c = renameAll(current.innerText.trim());
var buttons = document.getElementsByName("myBtnContainer");
var group = current;
do {
group = group.parentElement;
if (group.getAttribute("name") == "myBtnContainer") {
for (i = 0;i<buttons.length;i++) {
if (buttons[i] === group) {
group = i + 1;
break;
}
}
break;
}
} while (true);
var has = filtersList[c];
if (!has) {
if (filtersList.all && group == 1) filtersList = {};
if (c == 'all') filtersList = { all:1 }
else filtersList[c] = group;
} else {
delete filtersList[c];
if (c == 'all') filtersList = {};
}
var records = document.getElementsByClassName("column");
var matched = 0, filtersNo = [null,null];
updateButtons(buttons, filtersNo);
for (i = 0; i < records.length; i++) {
w3RemoveClass(records[i], "show");
var matchedFilters = [0,0];
for(var c1 in filtersList) {
var group = filtersList[c1]-1;
if (c1 == "all") c1 = "";
if (records[i].className.indexOf(c1) > -1) {
matchedFilters[group]++;
}
}
// Display trick here 2 binary numbers or logic table - each bit means non-zero number in group (matched > 0 / selected filter > 0) - hope works properly ;-)
var matched = (!!matchedFilters[0]) + (!!matchedFilters[1])*2;
var filters = (!!filtersNo[0]) + (!!filtersNo[1])*2;
if ((matched & filters) == filters && (filters != 0)) {
w3AddClass(records[i], "show");
}
}
updateButtons(buttons, filtersNo);
}
function updateButtons(buttons, filtersNo) {
filtersNo[0] = 0;
filtersNo[1] = 0;
for (i = 0;i<buttons.length;i++) {
if (i && !filtersNo[0]) filtersList = {};
for (var j = 0;j<buttons[i].children.length;j++) {
var el = buttons[i].children[j];
c = renameAll(el.innerHTML.trim());
if (filtersList[c]) {
filtersNo[i]++;
if (el.className.indexOf("active") < 0) el.className += " active";
} else {
el.className = el.className.replace(/[ ]*active[ ]*/,'');
}
}
}
if (filtersNo[0]) {
buttons[1].style.display = "";
} else {
buttons[1].style.display = "none";
}
}
function w3AddClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {
element.className += " " + arr2[i];
}
}
}
function w3RemoveClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
}
* {
box-sizing: border-box;
}
body {
background-color: #f1f1f1;
padding: 20px;
font-family: Arial;
}
/* Center website */
.main {
max-width: 1000px;
margin: auto;
}
h1 {
font-size: 50px;
word-break: break-all;
}
.row {
margin: 8px -16px;
}
/* Add padding BETWEEN each column */
.row,
.row>.column {
padding: 8px;
}
/* Create four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
display: none;
/* Hide all elements by default */
}
/* Clear floats after rows */
.row:after {
content: "";
display: table;
clear: both;
}
/* Content */
.content {
background-color: white;
padding: 10px;
}
/* The "show" class is added to the filtered elements */
.show {
display: block;
}
/* Style the buttons */
.btn {
border: none;
outline: none;
padding: 12px 16px;
background-color: white;
cursor: pointer;
}
.btn:hover {
background-color: #ddd;
}
.btn.active {
background-color: #666;
color: white;
}
/* Responsive layout - makes a two column-layout instead of four columns */
@media screen and (max-width: 900px) {
.column {
width: 50%;
}
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
@media screen and (max-width: 600px) {
.column {
width: 100%;
}
}
<div class="main">
<div name="myBtnContainer">
<button class="btn" onclick="filterSelection(this)"> Show all</button>
<button class="btn" onclick="filterSelection(this)"> 5-8</button>
<button class="btn" onclick="filterSelection(this)"> 8-10</button>
<button class="btn" onclick="filterSelection(this)"> 10+</button>
</div>
<div name="myBtnContainer" style="display: none">
<button class="btn" onclick="filterSelection(this)"> Operations</button>
<button class="btn" onclick="filterSelection(this)"> Manufacturing</button>
</div>
<!-- Portfolio Gallery Grid -->
<div class="row">
<div class="column 8-10 Operations">
<div class="content">
<a href="https://mbaex2020.co/batchprofiledetails#7839de77-db6d-4c0e-9072-d60fb35d09c9" target="_blank">
<img src="https://img1.wsimg.com/isteam/ip/97d4b213-5779-4c13-95cf-100a6b778fe3/Bagish.jpg/:/rs=w:600,h:750,cg:true,m/cr=w:1200,h:750,a:cc" alt="Bagish" style="width:100%" ;height:auto;>
<h4>Bagish</h4>
<p>8+ Experience in Oil&Gas, Manufacturing</p>
</div>
</div>
<div class="column 10+ Operations">
<div class="content">
<a href="https://mbaex2020.co/batchprofiledetails#c55a69ed-2170-41cf-b71d-e6546bb77c14" target="_blank">
<img src="https://img1.wsimg.com/isteam/ip/97d4b213-5779-4c13-95cf-100a6b778fe3/Rahul.jpg/:/rs=w:600,h:750,cg:true,m/cr=w:1200,h:750,a:cc" alt="Rahul" style="width:100%" ;height:auto;>
<h4>Rahul</h4>
<p>10+ Experience in Oil&Gas, Manufacturing</p>
</div>
</div>
<div class="column 10+">
<div class="content">
<a href="https://mbaex2020.co/batchprofiledetails#c26922ff-3ee8-4d1e-92bf-974f46061d40" target="_blank">
<img src="https://img1.wsimg.com/isteam/ip/97d4b213-5779-4c13-95cf-100a6b778fe3/Nikhil.jpg/:/rs=w:600,h:750,cg:true,m/cr=w:1200,h:750,a:cc" alt="Nikhil" style="width:100%" ;height:auto;>
<h4>Nikhil</h4>
<p>13+ Experience in IT Program Management</p>
</div>
</div>
<!-- END GRID -->
</div>
<!-- END MAIN -->
</div>
推荐阅读
- node.js - 如何让机器人在只有特定用户才能看到的 Discord 频道中发送消息?
- java - Dockerfile 添加命令未能找到目标文件夹
- php - 如何防止以任何方式从其目录中访问 PHP?
- python - 使用 Selenium Python 获取“数据标签”属性
- c# - 如何确保将文件保存在 Web 根文件夹中的安全性
- reactjs - Redux:无法读取未定义的属性“updateValue”
- bash - 来自 Git-Bash 的 Curl 请求未发送 Content-Type 标头
- bash - 如何从此文件中获取值?
- python - 根据列值拆分/扩展数据框
- amazon-web-services - 从 s3 中的 csv 文件跳过页脚到 Athena