<ul class="filter mb-30">
<li class="filter__btn" data-target="all">ALL</li>
<li class="filter__btn" data-target="red">RED</li>
<li class="filter__btn" data-target="blue">BLUE</li>
<li class="filter__btn" data-target="yellow">YELLOW</li>
<li class="filter__btn" data-target="green">GREEN</li>
</ul>
<ul class="filter__list">
<li class="filter__item red">item01</li>
<li class="filter__item blue">item02</li>
<li class="filter__item red">item03</li>
<li class="filter__item blue">item04</li>
<li class="filter__item yellow">item05</li>
<li class="filter__item green">item06</li>
<li class="filter__item yellow">item07</li>
<li class="filter__item green">item08</li>
<li class="filter__item red">item09</li>
<li class="filter__item yellow">item10</li>
<li class="filter__item green">item11</li>
<li class="filter__item blue">item12</li>
<li class="filter__item blue">item13</li>
<li class="filter__item yellow">item14</li>
<li class="filter__item red">item15</li>
<li class="filter__item green">item16</li>
</ul>
.filter > li {
display: inline-block;
padding: 8px 12px;
margin-right: 12px;
background: #333;
color: #fff;
border-radius: 8px;
cursor: pointer;
}
.filter__list {
display: flex;
flex-wrap: wrap;
transition: opacity 0.3s;
}
.filter__item {
display: flex;
width: 80px;
height: 80px;
line-height: 80px;
margin: 0 12px 12px 0;
color: #fff;
align-items: center;
justify-content: center;
}
.filter__item.red {
background: red;
}
.filter__item.blue {
background: blue;
}
.filter__item.yellow {
background: yellow;
}
.filter__item.green {
background: green;
}
.filter {
& > li {
display: inline-block;
padding: $space_sm $space_md;
margin-right: $space_md;
background: $color_main;
color: $color_opposite;
border-radius: $radius_md;
cursor: pointer;
}
&__list {
display: flex;
flex-wrap: wrap;
transition: opacity $speed_fast;
}
&__item {
display: flex;
width: 80px;
height: 80px;
line-height: 80px;
margin: 0 $space_md $space_md 0;
color: $color_opposite;
align-items: center;
justify-content: center;
&.red {
background: red;
}
&.blue {
background: blue;
}
&.yellow {
background: yellow;
}
&.green {
background: green;
}
}
}
(function() {
const filterBtns = document.querySelectorAll('.filter__btn');
const filterList = document.querySelector('.filter__list');
if(!filterList) {return;}
const filterItems = document.querySelectorAll('.filter__item');
let filterFlag = false;
let currentFilter;
transitionSet();
filterBtns.forEach(btn => {
btn.addEventListener('click', () => {
filterFlag = true;
currentFilter = btn.dataset.target;
hideItems();
});
});
function itemFilter() {
filterItems.forEach(item => {
item.style.display = '';
// 現在のフィルターと一致しない要素を非表示にする
if(!item.classList.contains(currentFilter) && currentFilter != 'all') {
item.style.display = 'none';
}
});
filterFlag = false;
showItems();
}
function showItems() {
filterList.style.opacity = 1;
}
function hideItems() {
filterList.style.opacity = 0;
}
function transitionSet() {
// ※アイテム要素全体のopacityを変化させて表示・非表示を切り替えることで、transitionendの対象を一つにできる
filterList.addEventListener('transitionend', () => {
if(filterFlag) {
itemFilter();
}
})
}
}());