Как отфильтровать элементы по клику?
У меня есть контейнер с набором разных элементов. Все элементы отличаются по цветам. Всего три цвета. Каждому элементу присвоено имя стилевого класса (class), которое позволяет связать каждый элемент с нужным для него стилевым оформлением. Элементы в общем контейнере не сгруппированы по цветам, и по факту находятся в нем вразброс. Визуально это выглядит так:
Вот html и css код:
body {overflow: hidden; width: 100%; margin: 0; text-align: center;}
.container {width: 100%; margin: 0 auto;}
.filter {
float: left; cursor: pointer; width: 23%;
margin: 0.5%; margin-bottom: 10px; padding: 0.5%;
background: white; text-align: center; color: black;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.2);
}
.item {
float: left; width: 23%; height: 20px; line-height: 20px;
margin: 0.5%; padding: 0.5%;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.2);
transition: all 1s;
}
.blue {background: deepskyblue;}
.red {background: orangered;}
.green {background: limegreen;}
<div class="container">
<div class="filter">Синий</div>
<div class="filter">Красный</div>
<div class="filter">Зеленый</div>
<div class="filter">Показать все</div>
<div class="item blue">1</div>
<div class="item red">2</div>
<div class="item blue">3</div>
<div class="item green">4</div>
<div class="item blue">5</div>
<div class="item red">6</div>
<div class="item red">7</div>
<div class="item green">8</div>
<div class="item blue">9</div>
<div class="item green">10</div>
<div class="item red">11</div>
<div class="item green">12</div>
<div class="item blue">13</div>
<div class="item blue">14</div>
<div class="item green">15</div>
<div class="item red">16</div>
</div>
Вопрос: Как при клике на название цвета отфильтровать все элементы таким образом, чтобы показать только элементы выбранного цвета, а все остальные спрятать? Например, при клике на "Красный" должно получится так:
Интересует реализация любыми средствами и технологиями, указанными в метках вопроса. Это может быть: CSS, jQuery, Native Script.
Ответы (4 шт):
Вариант CSS:
body {overflow: hidden; width: 100%; margin: 0; text-align: center;}
.container {width: 100%; margin: 0 auto;}
input[type="radio"] {display: none;}
label {
float: left; cursor: pointer; width: 23%;
margin: 0.5%; margin-bottom: 10px; padding: 0.5%;
background: white; text-align: center; color: black;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.2);
}
.blue, #blue:checked+label {background: deepskyblue;}
.red, #red:checked+label {background: orangered;}
.green, #green:checked+label {background: limegreen;}
.item {
float: left; width: 23%; height: 20px; line-height: 20px;
margin: 0.5%; padding: 0.5%;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.2);
transition: all 1s;
}
#blue:checked~.item:not(.blue),
#red:checked~.item:not(.red),
#green:checked~.item:not(.green) {
width: 0; height: 0;
margin: 0; padding: 0;
opacity: 0;
}
<div class="container">
<input type="radio" id="blue" name="color">
<label for="blue">Синий</label>
<input type="radio" id="red" name="color">
<label for="red">Красный</label>
<input type="radio" id="green" name="color">
<label for="green">Зеленый</label>
<input type="radio" id="reset" name="color">
<label for="reset">Показать все</label>
<div class="item blue">1</div>
<div class="item red">2</div>
<div class="item blue">3</div>
<div class="item green">4</div>
<div class="item blue">5</div>
<div class="item red">6</div>
<div class="item red">7</div>
<div class="item green">8</div>
<div class="item blue">9</div>
<div class="item green">10</div>
<div class="item red">11</div>
<div class="item green">12</div>
<div class="item blue">13</div>
<div class="item blue">14</div>
<div class="item green">15</div>
<div class="item red">16</div>
</div>
Вариант jQuery:
$(".f__blue").click(function() {
$(".f__red").removeClass("red__active");
$(".f__green").removeClass("green__active");
$(this).addClass("blue__active");
$(".blue").removeClass("hide");
$(".red, .green").addClass("hide");
});
$(".f__red").click(function() {
$(".f__blue").removeClass("blue__active");
$(".f__green").removeClass("green__active");
$(this).addClass("red__active");
$(".red").removeClass("hide");
$(".blue, .green").addClass("hide");
});
$(".f__green").click(function() {
$(".f__blue").removeClass("blue__active");
$(".f__red").removeClass("red__active");
$(this).addClass("green__active");
$(".green").removeClass("hide");
$(".blue, .red").addClass("hide");
});
$(".reset").click(function() {
$(".f__blue").removeClass("blue__active");
$(".f__red").removeClass("red__active");
$(".f__green").removeClass("green__active");
$(".blue, .red, .green").removeClass("hide");
});
body {overflow: hidden; width: 100%; margin: 0; text-align: center;}
.container {width: 100%; margin: 0 auto;}
.item {
float: left; width: 23%; height: 20px; line-height: 20px;
margin: 0.5%; padding: 0.5%;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.2);
transition: all 1s;
}
.hide {
width: 0; height: 0;
margin: 0; padding: 0;
opacity: 0;
}
.filter {
float: left; cursor: pointer; width: 23%;
margin: 0.5%; margin-bottom: 10px; padding: 0.5%;
background: white; text-align: center; color: black;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.2);
}
.blue, .blue__active {background: deepskyblue;}
.red, .red__active {background: orangered;}
.green, .green__active {background: limegreen;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="filter f__blue">Синий</div>
<div class="filter f__red">Красный</div>
<div class="filter f__green">Зеленый</div>
<div class="filter reset">Показать все</div>
<div class="item blue">1</div>
<div class="item red">2</div>
<div class="item blue">3</div>
<div class="item green">4</div>
<div class="item blue">5</div>
<div class="item red">6</div>
<div class="item red">7</div>
<div class="item green">8</div>
<div class="item blue">9</div>
<div class="item green">10</div>
<div class="item red">11</div>
<div class="item green">12</div>
<div class="item blue">13</div>
<div class="item blue">14</div>
<div class="item green">15</div>
<div class="item red">16</div>
</div>
Вариант JavaScript:
const fb = document.querySelector('.f__blue');
const fr = document.querySelector('.f__red');
const fg = document.querySelector('.f__green');
const reset = document.querySelector('.reset');
const all = document.querySelectorAll('.item');
const blue = document.querySelectorAll('.blue');
const red = document.querySelectorAll('.red');
const green = document.querySelectorAll('.green');
fb.onclick = function(){
fr.classList.remove("red__active");
fg.classList.remove("green__active");
this.classList.add("blue__active");
for(var i = 0; i < all.length; i++){
all[i].classList.add("hide");
}
for(var i = 0; i < blue.length; i++){
blue[i].classList.remove("hide");
}
}
fr.onclick = function(){
fb.classList.remove("blue__active");
fg.classList.remove("green__active");
this.classList.add("red__active");
for(var i = 0; i < all.length; i++){
all[i].classList.add("hide");
}
for(var i = 0; i < red.length; i++){
red[i].classList.remove("hide");
}
}
fg.onclick = function(){
fb.classList.remove("blue__active");
fr.classList.remove("red__active");
this.classList.add("green__active");
for(var i = 0; i < all.length; i++){
all[i].classList.add("hide");
}
for(var i = 0; i < green.length; i++){
green[i].classList.remove("hide");
}
}
reset.onclick = function(){
fb.classList.remove("blue__active");
fr.classList.remove("red__active");
fg.classList.remove("green__active");
for(var i = 0; i < all.length; i++){
all[i].classList.remove("hide");
}
}
body {overflow: hidden; width: 100%; margin: 0; text-align: center;}
.container {width: 100%; margin: 0 auto;}
.item {
float: left; width: 23%; height: 20px; line-height: 20px;
margin: 0.5%; padding: 0.5%;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.2);
transition: all 1s;
}
.hide {
width: 0; height: 0;
margin: 0; padding: 0;
opacity: 0;
}
.filter {
float: left; cursor: pointer; width: 23%;
margin: 0.5%; margin-bottom: 10px; padding: 0.5%;
background: white; text-align: center; color: black;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.2);
}
.blue, .blue__active {background: deepskyblue;}
.red, .red__active {background: orangered;}
.green, .green__active {background: limegreen;}
<div class="container">
<div class="filter f__blue">Синий</div>
<div class="filter f__red">Красный</div>
<div class="filter f__green">Зеленый</div>
<div class="filter reset">Показать все</div>
<div class="item blue">1</div>
<div class="item red">2</div>
<div class="item blue">3</div>
<div class="item green">4</div>
<div class="item blue">5</div>
<div class="item red">6</div>
<div class="item red">7</div>
<div class="item green">8</div>
<div class="item blue">9</div>
<div class="item green">10</div>
<div class="item red">11</div>
<div class="item green">12</div>
<div class="item blue">13</div>
<div class="item blue">14</div>
<div class="item green">15</div>
<div class="item red">16</div>
</div>
Варианты с JS, лучше делать более универсальными - не зависящими от кол-ва цветов.
const btsFilter = Array.from(document.querySelectorAll('[data-filter]'))
const colors = ['blue', 'green', 'red' /*, .... */]
const map = colors.reduce((a, e) => {
const bt = btsFilter.find((btel) => btel.dataset.filter === e)
const els = Array.from(document.querySelectorAll(`.item.${e}`))
let hide = false
a.set(e, (fl, reset) => {
if (fl) {
reset || bt.classList.add('selected')
if (!hide) return
hide = false
els.forEach((e) => e.classList.remove('hide'))
} else {
bt.classList.remove('selected')
if (hide) return
hide = true
els.forEach((e) => e.classList.add('hide'))
}
})
return a
}, new Map())
map.set('reset', (fl) => fl && colors.forEach((e) => map.get(e)(fl, true)))
btsFilter.forEach((i) => i.addEventListener('click', ({ target: { dataset: { filter } } }) => {
for (let [key, show] of map.entries()) {
show(filter === key)
}
}))
body {
overflow: hidden;
width: 100%;
margin: 0;
text-align: center;
}
.container {
width: 100%;
margin: 0 auto;
}
.item {
float: left;
width: 23%;
height: 20px;
line-height: 20px;
margin: 0.5%;
padding: 0.5%;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.2);
transition: all 1s;
}
.hide {
width: 0;
height: 0;
margin: 0;
padding: 0;
opacity: 0;
}
.filter {
float: left;
cursor: pointer;
width: 23%;
margin: 0.5%;
margin-bottom: 10px;
padding: 0.5%;
background: white;
text-align: center;
color: black;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.2);
}
.blue,
.filter.selected[data-filter="blue"] {
background: deepskyblue;
}
.red,
.filter.selected[data-filter="red"] {
background: orangered;
}
.green,
.filter.selected[data-filter="green"] {
background: limegreen;
}
<div class="filter" data-filter="blue">Синий</div>
<div class="filter" data-filter="red">Красный</div>
<div class="filter" data-filter="green">Зеленый</div>
<div class="filter" data-filter="reset">Показать все</div>
<div class="item blue">1</div>
<div class="item red">2</div>
<div class="item blue">3</div>
<div class="item green">4</div>
<div class="item blue">5</div>
<div class="item red">6</div>
<div class="item red">7</div>
<div class="item green">8</div>
<div class="item blue">9</div>
<div class="item green">10</div>
<div class="item red">11</div>
<div class="item green">12</div>
<div class="item blue">13</div>
<div class="item blue">14</div>
<div class="item green">15</div>
<div class="item red">16</div>

