首页 > 解决方案 > 如何使用 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/运营等添加另一个级别的过滤器。

标签: javascripthtmlrecursionbuttonfilter

解决方案


进行了一些调整和简化,但假设可以按您的意愿工作;-)
如果您满意,请记住按接受按钮(正在投票中)。

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>


推荐阅读