javascript - 如果另一个类的复选框已被选中,如何从 jQuery 过滤器中排除某个复选框类?
问题描述
我是编码新手,不知道自己在做什么。我觉得我也不太擅长解释事情,所以如果这篇文章有点难以理解,我很抱歉。希望查看代码本身更有意义。
基本上,我有一个可以过滤的列表。每个列表项包含多个类。我也有复选框来显示每个单独的类。
但是,有几个类在它们适用的列表项方面重叠,但并不完全相同。
例如,有人要查找 A 类中的内容,但不包含 D 类中的内容。如果选中 A 类,它将自动显示 D 类也适用的所有列表项。
我想做的是,如果选中 A 类,您还可以选择从搜索中排除 D 类,以便显示重叠数据。反之亦然(即如果选中 D 类,则可以选择排除 A 类)。
如果可能的话,我也希望这适用于所有课程。这样您就可以检查一个(或多个)类,但同时排除您不感兴趣的某个类,即使列表项重叠(即您已选中 D 类,并且不想要列表项在 B 类中也属于 D 类)。
<div class="options">
<label>
<input type="radio" name="operation" value="union" id="op-union" checked>Union
</label>
<label>
<input type="radio" name="operation" value="intersection" id="op-inter">Intersection
</label>
</div>
<div class="categories">
<span class="category">
<input type="checkbox" value="classa" id="cat-classa">
<label for="cat-classa">Class A</label>
</span>
<span class="category">
<input type="checkbox" value="classb" id="cat-classb">
<label for="cat-classb">Class B</label>
</span>
<span class="category">
<input type="checkbox" value="classc" id="cat-classc">
<label for="cat-classc">Class C</label>
</span>
<span class="category">
<input type="checkbox" value="classd" id="cat-classd">
<label for="cat-classd">Class D</label>
</span>
<span class="category">
<input type="checkbox" value="classe" id="cat-classe">
<label for="cat-classe">Class E</label>
</span>
<span class="category">
<input type="checkbox" value="classf" id="cat-classf">
<label for="cat-classf">Class F</label>
</span>
</div>
<div class="container">
<ul>
<div class="filterDiv classa classd"><li>List 1</li></div>
<div class="filterDiv classa classe"><li>List 2</li></div>
<div class="filterDiv classb classd classe"><li>List 3</li></div>
<div class="filterDiv classc classf">List 4</li></div>
<div class="filterDiv classb classd classf">List 5</li></div>
</ul>
</div>
鉴于列表的性质,类和类型的任何组合都是可能的。通常,只有一堂课,但有时有两堂课。在实际列表中,我的一个列表项也不仅仅是三个类。
脚本:
<script>
var checkboxes = document.querySelectorAll(".categories input");
for(var i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener("change", filter);
}
var radios = document.getElementsByName("operation");
for(var i = 0; i < radios.length; i++) {
radios[i].addEventListener("change", filter);
}
filter();
function filter() {
var i, j;
// Choose an operation
var operation = document.getElementById("op-union").checked ? "union" : "intersection";
// Get the selected categories
var checkboxes = document.querySelectorAll(".categories input");
var categories = [];
var c;
for(i = 0; i < checkboxes.length; i++) {
if(checkboxes[i].checked) {
c = checkboxes[i].value;
categories.push(c);
}
}
// Apply the filter
var items = document.querySelectorAll(".filterDiv");
var item, show;
for(i = 0; i < items.length; i++) {
item = items[i];
if(categories.length == 0) {
show = true;
} else if(operation == "union") {
// Union: Only one of the categories needs to exist
show = false;
for(j = 0; j < categories.length; j++) {
if(item.classList.contains(categories[j])) {
show = true;
break;
}
}
} else {
// Intersection: All of the categories must apply
show = true;
for(j = 0; j < categories.length; j++) {
if(!item.classList.contains(categories[j])) {
show = false;
break;
}
}
}
if(show) {
item.classList.add("show");
} else {
item.classList.remove("show");
}
}
}
</script>
提前感谢任何帮助的人!我再次为措辞道歉,我对此并不陌生,并且仍在想办法解决这一切。任何尝试都非常感谢。
解决方案
你的代码很好。你需要一些修改。我没有改变你的代码风格,但如果你使用 javascript 更好地使用 let 关键字(现代 javascript)不要再使用 var 并尝试理解减少你的代码的 forEach 循环(除非你正在使用 break 语句)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="options">
<label><input type="radio" name="operation" value="union" id="op-union" checked>A or B</label>
<label><input type="radio" name="operation" value="intersection" id="op-inter">A and B</label>
</div>
<div class="categories">
<span class="category"><input type="checkbox" value="classa" id="cat-classa"><label for="cat-classa">Class A</label></span>
<span class="category"><input type="checkbox" value="classb" id="cat-classb"><label for="cat-classb">Class B</label></span>
<span class="category"><input type="checkbox" value="classc" id="cat-classc"><label for="cat-classc">Class C</label></span>
<span class="category"><input type="checkbox" value="classd" id="cat-classd"><label for="cat-classd">Class D</label></span>
<span class="category"><input type="checkbox" value="classe" id="cat-classe"><label for="cat-classe">Class E</label></span>
<span class="category"><input type="checkbox" value="classf" id="cat-classf"><label for="cat-classf">Class F</label></span>
</div>
<div class="container">
<ul>
<div class="filterDiv classa classd"><li>List 1</li></div>
<div class="filterDiv classa classe"><li>List 2</li></div>
<div class="filterDiv classb classd classe"><li>List 3</li></div>
<div class="filterDiv classc classf">List 4</li></div>
<div class="filterDiv classb classd classf">List 5</li></div>
</ul>
</div>
<script>
var checkboxes = document.querySelectorAll(".categories input");
for(var i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener("change", filter);
}
var radios = document.getElementsByName("operation");
for(var i = 0; i < radios.length; i++) {
radios[i].addEventListener("change", filter);
}
filter();
function filter() {
var i, j;
// Choose an operation
var operation = document.getElementById("op-union").checked ? "union" : "intersection";
// Get the selected categories
var checkboxes = document.querySelectorAll(".categories input");
var categories = [];
var c;
for(i = 0; i < checkboxes.length; i++) {
if(checkboxes[i].checked) {
c = checkboxes[i].value;
categories.push(c);
}
}
// Apply the filter
var items = document.querySelectorAll(".filterDiv");
items.forEach(item=>item.style.display='block')
var item, show;
for(i = 0; i < items.length; i++) {
item = items[i];
if(categories.length == 0) {
show = true;
} else if(operation == "union") {
// Union: Only one of the categories needs to exist
show = false;
for(j = 0; j < categories.length; j++) {
if(item.classList.contains(categories[j])) {
show = true;
break;
}
}
if(!show){
item.style.display="none";
}
} else {
// console.log(operation)
// Intersection: All of the categories must apply
show = true;
for(j = 0; j < categories.length; j++) {
if(!item.classList.contains(categories[j])) {
item.style.display="none";
break;
}
}
}
// if(show) {
// item.classList.add("show");
// } else {
// item.classList.remove("show");
// }
}
}
</script>
</body>
</html>
推荐阅读
- arrays - 尝试使用 PowerShell 从数组的对象部分访问每个元素
- python - 如何在 Django 模板中正确地为 URL 提供参数?
- windows - 为文件中不可能存在的 Winsock 查找终止字符
- cmake - TI cl2000 cmake CXX 编译识别未知
- android - 如何在 EditText 中存储自定义对象/属性?
- angular - 使用 index.html 离线运行 Angular 7 Web 应用程序
- javascript - 为什么这样的递归没有堆栈溢出?
- c# - Azure 托管标识本地调试身份验证失败
- python - 动态变化的小部件
- python - 在回调期间为多个输入/状态重命名破折号菜单属性