Reputation:
I am practicing how to use filter and wanted to create a simple "portfolio" mockup that lets you click a button and it filters the results. I can't seem to figure out why it isn't working.
let posts = [...document.querySelectorAll('.post')];
let btns = [...document.querySelectorAll('.btn')];
for( let b of btns) {
b.addEventListener('click', () => {
let buttonClass = b.getAttribute('id');
posts.filter((post) => {
return post.classList.contains(buttonClass);
});
});
}
.container {
width: 90%;
margin: 2rem auto;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
grid-gap: 1rem;
}
.post {
width: 100%;
height: 100%;
transition: all 0.3s;
}
.blue {
background: #192331;
}
.black {
background: #171717;
}
<button id="all" class="btn">All</button>
<button id="blue" class="btn">Blue</button>
<button id="black" class="btn">Black</button>
<div class="container">
<div class="post blue"></div>
<div class="post black"></div>
<div class="post black"></div>
<div class="post blue"></div>
<div class="post blue"></div>
<div class="post black"></div>
</div>
Upvotes: 1
Views: 75
Reputation: 8610
Working off of Williams answer and covering the animation... Do the transition animation with opacity and keyframes in CSS, then use a setTimeout that sets the display to none after the opacity animation runs.
So you have a setTimeout that runs 10 ms after the opacity conditional fires, this allows the animation to fire and then sets the display to none, basically removing the opaque elements from view on the browser. Sense the classes are set up as a toggle in JS, you use them in your setTimeout function.
See the code below.
let posts = [...document.querySelectorAll('.post')];
let btns = [...document.querySelectorAll('.btn')];
let cont = [...document.querySelectorAll('.container')];
function setDisplay(el) {
if(el.classList.contains('hide')){
el.style.display = 'none';
}else{
el.style.display = 'block';
}
}
for (let b of btns) {
b.addEventListener('click', () => {
let buttonClass = b.getAttribute('id');
posts.forEach((post) => {
if (post.classList.contains(buttonClass)) {
post.classList.remove('hide')
post.classList.add('show')
setTimeout(setDisplay(post), 10)
} else {
post.classList.remove('show')
post.classList.add('hide')
setTimeout(setDisplay(post), 10)
}
});
});
}
.container {
width: 90%;
margin: 2rem auto;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
grid-gap: 1rem;
}
.post {
width: 100%;
height: 100%;
}
.blue {
background: #192331;
}
.black {
background: #171717;
}
.show {
animation: showme .5s ease-in;
}
@keyframes showme {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.hide {
opacity: 0;
animation: hideme .5s ease-out;
}
@keyframes hideme {
0% {
opacity: 1
}
100% {
opacity: 0
}
}
<button id="post" class="btn">All</button>
<button id="blue" class="btn">Blue</button>
<button id="black" class="btn">Black</button>
<div class="container">
<div class="post blue"></div>
<div class="post black"></div>
<div class="post black"></div>
<div class="post blue"></div>
<div class="post blue"></div>
<div class="post black"></div>
</div>
Upvotes: 1
Reputation: 8751
Filter doesn't work. Just use toggling way to add/remove show
and hide
class to the post containers.
let posts = [...document.querySelectorAll('.post')];
let btns = [...document.querySelectorAll('.btn')];
for( let b of btns) {
b.addEventListener('click', () => {
let buttonClass = b.getAttribute('id');
posts.forEach((post) => {
if (post.classList.contains(buttonClass)) {
post.classList.remove('hide')
post.classList.add('show')
}
else {
post.classList.remove('show')
post.classList.add('hide')
}
});
});
}
.container {
width: 90%;
margin: 2rem auto;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
grid-gap: 1rem;
}
.post {
width: 100%;
height: 100%;
transition: all 0.3s;
}
.blue {
background: #192331;
}
.black {
background: #171717;
}
.show {
display: block;
}
.hide {
display: none;
}
<button id="post" class="btn">All</button>
<button id="blue" class="btn">Blue</button>
<button id="black" class="btn">Black</button>
<div class="container">
<div class="post blue"></div>
<div class="post black"></div>
<div class="post black"></div>
<div class="post blue"></div>
<div class="post blue"></div>
<div class="post black"></div>
</div>
Upvotes: 1