如何使用 javascript 过滤 div?
How to filter divs with javascript?
我正在尝试使用 javascript 创建过滤器。我想要完成的是:
单击复选框时,每个 div 与所选 class(汽车或动物)应显示(显示:方块),其他 div 不包含它应该隐藏(显示:none)。
我想出了下面的代码,但它并没有像我想的那样工作。只有在您选中这两个复选框后它才会起作用,但是包含汽车和动物的 classes 会被隐藏。它应该显示它是否包含其中之一。
这个想法很简单,看看复选框是否被选中,然后将它们推送到一个数组中。如果它在该数组中,则更改为 "display: block",否则添加 "display: none"。但正如我所说,有些地方不对劲.. 知道可能是什么问题吗?
Javascript:
let anotherOne = (x) => {
let all = document.getElementsByClassName('filterDiv'); //all filterable divs
let checkBoxCars = document.getElementById('cars');
let checkBoxAnimals = document.getElementById('animals');
let elements = document.getElementsByClassName(x); //divs with selected class
//Empty arrays for pushing checked and unchecked boxes.
let isChecked = []
let unChecked = []
if (checkBoxCars.checked == true) {
isChecked.push('cars')
} else {
unChecked.push('cars')
}
if (checkBoxAnimals.checked == true) {
isChecked.push('animals')
} else {
unChecked.push('animals')
}
//if checkbox value is in checked array then
if (isChecked.indexOf(x) > -1) {
//In the array
for (i = 0; i < elements.length; i++) {
elements[i].style.display = "block";
}
} else {
//Not in the array
for (i = 0; i < elements.length; i++) {
elements[i].style.display = "none";
}
}
//If all checkboxes is unset, show all
if (isChecked.length == 0) {
for (i = 0; i < all.length; i++) {
all[i].style.display = "block";
}
}
}
HTML:
<body>
<div id="myBtnContainer">
<input type="checkbox" id="cars" onclick="anotherOne('cars')">
<label for="cars">cars</label>
<input type="checkbox" id="animals" onclick="anotherOne('animals')">
<label for="animals">animals</label>
</div>
<!-- The filterable elements. Note that some have multiple class names (this can be used if they belong to multiple categories) -->
<div class="container">
<div id="cars" class="filterDiv show cars">BMW</div>
<div class="filterDiv show cars animals">CarDog1</div>
<div class="filterDiv show cars">Volvo</div>
<div class="filterDiv show cars">Mustang</div>
<div class="filterDiv show animals">Cat</div>
<div class="filterDiv show animals">Dog</div>
<div class="filterDiv show cars animals">CarDog2</div>
<div class="filterDiv show animals">Cow</div>
</div>
</body>
一种方法如下,但请记住,我从以下元素中删除了重复的 id
:
<div id="cars" class="filterDiv show cars">BMW</div>
因为 id
也用于 - 更恰当地 - 用于 <input>
元素,并且重复的 id
会使文档无效并导致 JavaScript 出现问题。
这是我对 HTML 所做的唯一更改,演示如下:
// use of a named function, composed using an Arrow function expression,
// as we don't need to refer to a 'this' within the function, here we
// also pass in the Event Object ('e') from the use of
// EventTarget.addEventListener() (later):
const filterToggle = (e) => {
// here use document.querySelectorAll() to find all <input>
// elements with a type-attribute with that value set to
// 'checkbox' which is also checked; we then use the spread
// operator to convert the iterable NodeList into an Array:
const checkedFilters = [
...document.querySelectorAll('input[type=checkbox]:checked')
// we then use Array.prototype.map():
].map(
// to create an Array of the checked check-boxes id properties:
(el) => el.id
),
// we then derive an Array, as above, of all elements matching
// the '.filterDiv' selector:
toFilter = [...document.querySelectorAll('.filterDiv')];
// if there are no checked filters we show all elements:
if (checkedFilters.length === 0) {
// iterating over the Array of nodes using
// Array.prototype.forEach() along with an anonymous
// Arrow function expression to update the display
// property to 'block':
toFilter.forEach(
(el) => el.style.display = 'block'
)
} else {
// in the event that some check-boxes were checked,
// we first iterate over the .filterDiv elements to
// hide them all:
toFilter.forEach(
(el) => el.style.display = 'none'
);
// then create a new Array from the checkedFilters
// Array using Array.prototype.map():
let selector = checkedFilters.map(
// here we use a template-literal to create a string of
// '.filterDiv.<filter-id>'
(f) => `.filterDiv.${f}`
// then we join the elements of the Array of selectors
// together, into a String, using Array.prototype.join()
// using a comma (',')
).join(',');
// here we use document.querySelectorAll() with the
// created selector, and iterate over that NodeList
// using NodeList.prototype.forEach() to update the
// display of all elements matching the selector in
// order to show them again:
document.querySelectorAll(selector).forEach(
(el) => el.style.display = 'block'
);
}
},
// here we find the check-boxes:
filters = document.querySelectorAll('input[type=checkbox]');
// we iterate over the check-boxes using NodeList.prototype.forEach():
filters.forEach(
// along with an anonymous Arrow function expression, to bind the
// filterToggle() (note the deliberate lack of parentheses) as the
// event-handler for the 'change' event:
(f) => f.addEventListener('change', filterToggle)
);
const filterToggle = (e) => {
const checkedFilters = [...document.querySelectorAll('input[type=checkbox]:checked')].map(
(el) => el.id
),
toFilter = [...document.querySelectorAll('.filterDiv')];
if (checkedFilters.length === 0) {
toFilter.forEach(
(el) => el.style.display = 'block'
)
} else {
toFilter.forEach(
(el) => el.style.display = 'none'
);
let selector = checkedFilters.map(
(f) => `.filterDiv.${f}`
).join(',');
document.querySelectorAll(selector).forEach(
(el) => el.style.display = 'block'
);
}
},
filters = document.querySelectorAll('input[type=checkbox]');
filters.forEach(
(f) => f.addEventListener('change', filterToggle)
);
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-template-rows: 4em;
grid-auto-rows: 4em;
grid-gap: 0.5em;
}
.filterDiv {
border: 2px solid palegreen;
}
<div id="myBtnContainer">
<input type="checkbox" id="cars">
<label for="cars">cars</label>
<input type="checkbox" id="animals">
<label for="animals">animals</label>
</div>
<!-- The filterable elements. Note that some have multiple class names (this can be used if they belong to multiple categories) -->
<div class="container">
<div class="filterDiv show cars">BMW</div>
<div class="filterDiv show cars animals">CarDog1</div>
<div class="filterDiv show cars">Volvo</div>
<div class="filterDiv show cars">Mustang</div>
<div class="filterDiv show animals">Cat</div>
<div class="filterDiv show animals">Dog</div>
<div class="filterDiv show cars animals">CarDog2</div>
<div class="filterDiv show animals">Cow</div>
</div>
参考文献:
我自己解决了这个问题,让它变得比我最初想象的要简单,只保留了我的两个数组,根据是否选中它们将 类 推入两个数组,然后添加显示: none 并显示:阻止他们。适用于多个 类。我猜你有时会想太多..
这是我的解决方案:
let anotherOne = (x) => {
console.log(x)
let all = document.getElementsByClassName('filterDiv'); //all filterable divs
let checkBoxCars = document.getElementById('cars');
let checkBoxAnimals = document.getElementById('animals');
//remembers if checked
let isChecked = []
let unChecked = []
if (checkBoxCars.checked == true){isChecked.push('cars')}else{unChecked.push('cars')}
if (checkBoxAnimals.checked == true){isChecked.push('animals')}else{unChecked.push('animals')}
if (checkBoxPlant.checked == true){isChecked.push('plants')}else{unChecked.push('plants')}
console.log('checked: '+ isChecked + ' unchecked: ' + unChecked)
//Add display none to unChecked array
for(i=0;i<unChecked.length;i++) {
let getClass = document.getElementsByClassName(unChecked[i]);
for(c=0;c<getClass.length;c++) {
getClass[c].style.display ="none";
}}
//Add display block to isChecked array
for(i=0;i<isChecked.length;i++) {
let getClass = document.getElementsByClassName(isChecked[i]);
for(c=0;c<getClass.length;c++) {
getClass[c].style.display ="block";
}}
我正在尝试使用 javascript 创建过滤器。我想要完成的是:
单击复选框时,每个 div 与所选 class(汽车或动物)应显示(显示:方块),其他 div 不包含它应该隐藏(显示:none)。
我想出了下面的代码,但它并没有像我想的那样工作。只有在您选中这两个复选框后它才会起作用,但是包含汽车和动物的 classes 会被隐藏。它应该显示它是否包含其中之一。
这个想法很简单,看看复选框是否被选中,然后将它们推送到一个数组中。如果它在该数组中,则更改为 "display: block",否则添加 "display: none"。但正如我所说,有些地方不对劲.. 知道可能是什么问题吗?
Javascript:
let anotherOne = (x) => {
let all = document.getElementsByClassName('filterDiv'); //all filterable divs
let checkBoxCars = document.getElementById('cars');
let checkBoxAnimals = document.getElementById('animals');
let elements = document.getElementsByClassName(x); //divs with selected class
//Empty arrays for pushing checked and unchecked boxes.
let isChecked = []
let unChecked = []
if (checkBoxCars.checked == true) {
isChecked.push('cars')
} else {
unChecked.push('cars')
}
if (checkBoxAnimals.checked == true) {
isChecked.push('animals')
} else {
unChecked.push('animals')
}
//if checkbox value is in checked array then
if (isChecked.indexOf(x) > -1) {
//In the array
for (i = 0; i < elements.length; i++) {
elements[i].style.display = "block";
}
} else {
//Not in the array
for (i = 0; i < elements.length; i++) {
elements[i].style.display = "none";
}
}
//If all checkboxes is unset, show all
if (isChecked.length == 0) {
for (i = 0; i < all.length; i++) {
all[i].style.display = "block";
}
}
}
HTML:
<body>
<div id="myBtnContainer">
<input type="checkbox" id="cars" onclick="anotherOne('cars')">
<label for="cars">cars</label>
<input type="checkbox" id="animals" onclick="anotherOne('animals')">
<label for="animals">animals</label>
</div>
<!-- The filterable elements. Note that some have multiple class names (this can be used if they belong to multiple categories) -->
<div class="container">
<div id="cars" class="filterDiv show cars">BMW</div>
<div class="filterDiv show cars animals">CarDog1</div>
<div class="filterDiv show cars">Volvo</div>
<div class="filterDiv show cars">Mustang</div>
<div class="filterDiv show animals">Cat</div>
<div class="filterDiv show animals">Dog</div>
<div class="filterDiv show cars animals">CarDog2</div>
<div class="filterDiv show animals">Cow</div>
</div>
</body>
一种方法如下,但请记住,我从以下元素中删除了重复的 id
:
<div id="cars" class="filterDiv show cars">BMW</div>
因为 id
也用于 - 更恰当地 - 用于 <input>
元素,并且重复的 id
会使文档无效并导致 JavaScript 出现问题。
这是我对 HTML 所做的唯一更改,演示如下:
// use of a named function, composed using an Arrow function expression,
// as we don't need to refer to a 'this' within the function, here we
// also pass in the Event Object ('e') from the use of
// EventTarget.addEventListener() (later):
const filterToggle = (e) => {
// here use document.querySelectorAll() to find all <input>
// elements with a type-attribute with that value set to
// 'checkbox' which is also checked; we then use the spread
// operator to convert the iterable NodeList into an Array:
const checkedFilters = [
...document.querySelectorAll('input[type=checkbox]:checked')
// we then use Array.prototype.map():
].map(
// to create an Array of the checked check-boxes id properties:
(el) => el.id
),
// we then derive an Array, as above, of all elements matching
// the '.filterDiv' selector:
toFilter = [...document.querySelectorAll('.filterDiv')];
// if there are no checked filters we show all elements:
if (checkedFilters.length === 0) {
// iterating over the Array of nodes using
// Array.prototype.forEach() along with an anonymous
// Arrow function expression to update the display
// property to 'block':
toFilter.forEach(
(el) => el.style.display = 'block'
)
} else {
// in the event that some check-boxes were checked,
// we first iterate over the .filterDiv elements to
// hide them all:
toFilter.forEach(
(el) => el.style.display = 'none'
);
// then create a new Array from the checkedFilters
// Array using Array.prototype.map():
let selector = checkedFilters.map(
// here we use a template-literal to create a string of
// '.filterDiv.<filter-id>'
(f) => `.filterDiv.${f}`
// then we join the elements of the Array of selectors
// together, into a String, using Array.prototype.join()
// using a comma (',')
).join(',');
// here we use document.querySelectorAll() with the
// created selector, and iterate over that NodeList
// using NodeList.prototype.forEach() to update the
// display of all elements matching the selector in
// order to show them again:
document.querySelectorAll(selector).forEach(
(el) => el.style.display = 'block'
);
}
},
// here we find the check-boxes:
filters = document.querySelectorAll('input[type=checkbox]');
// we iterate over the check-boxes using NodeList.prototype.forEach():
filters.forEach(
// along with an anonymous Arrow function expression, to bind the
// filterToggle() (note the deliberate lack of parentheses) as the
// event-handler for the 'change' event:
(f) => f.addEventListener('change', filterToggle)
);
const filterToggle = (e) => {
const checkedFilters = [...document.querySelectorAll('input[type=checkbox]:checked')].map(
(el) => el.id
),
toFilter = [...document.querySelectorAll('.filterDiv')];
if (checkedFilters.length === 0) {
toFilter.forEach(
(el) => el.style.display = 'block'
)
} else {
toFilter.forEach(
(el) => el.style.display = 'none'
);
let selector = checkedFilters.map(
(f) => `.filterDiv.${f}`
).join(',');
document.querySelectorAll(selector).forEach(
(el) => el.style.display = 'block'
);
}
},
filters = document.querySelectorAll('input[type=checkbox]');
filters.forEach(
(f) => f.addEventListener('change', filterToggle)
);
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-template-rows: 4em;
grid-auto-rows: 4em;
grid-gap: 0.5em;
}
.filterDiv {
border: 2px solid palegreen;
}
<div id="myBtnContainer">
<input type="checkbox" id="cars">
<label for="cars">cars</label>
<input type="checkbox" id="animals">
<label for="animals">animals</label>
</div>
<!-- The filterable elements. Note that some have multiple class names (this can be used if they belong to multiple categories) -->
<div class="container">
<div class="filterDiv show cars">BMW</div>
<div class="filterDiv show cars animals">CarDog1</div>
<div class="filterDiv show cars">Volvo</div>
<div class="filterDiv show cars">Mustang</div>
<div class="filterDiv show animals">Cat</div>
<div class="filterDiv show animals">Dog</div>
<div class="filterDiv show cars animals">CarDog2</div>
<div class="filterDiv show animals">Cow</div>
</div>
参考文献:
我自己解决了这个问题,让它变得比我最初想象的要简单,只保留了我的两个数组,根据是否选中它们将 类 推入两个数组,然后添加显示: none 并显示:阻止他们。适用于多个 类。我猜你有时会想太多..
这是我的解决方案:
let anotherOne = (x) => {
console.log(x)
let all = document.getElementsByClassName('filterDiv'); //all filterable divs
let checkBoxCars = document.getElementById('cars');
let checkBoxAnimals = document.getElementById('animals');
//remembers if checked
let isChecked = []
let unChecked = []
if (checkBoxCars.checked == true){isChecked.push('cars')}else{unChecked.push('cars')}
if (checkBoxAnimals.checked == true){isChecked.push('animals')}else{unChecked.push('animals')}
if (checkBoxPlant.checked == true){isChecked.push('plants')}else{unChecked.push('plants')}
console.log('checked: '+ isChecked + ' unchecked: ' + unChecked)
//Add display none to unChecked array
for(i=0;i<unChecked.length;i++) {
let getClass = document.getElementsByClassName(unChecked[i]);
for(c=0;c<getClass.length;c++) {
getClass[c].style.display ="none";
}}
//Add display block to isChecked array
for(i=0;i<isChecked.length;i++) {
let getClass = document.getElementsByClassName(isChecked[i]);
for(c=0;c<getClass.length;c++) {
getClass[c].style.display ="block";
}}