Cancel Pending Settimeouts For Multiple Items In For Loop
I'm trying to create a cool little micro interaction, but I'm running into a minor issue. If you toggle in too quick of a succession, some items will ultimately be displayed, wher
Solution 1:
I would simplify your logic and consider transition-delay
where you only need to toggle a class. The trick is to have a different delay for your elements when we toggle the class to have the desired effect.
With this configuration you won't have any issue because all the element will have the same state since the class is added to their parent element.
var nav = document.querySelector('nav');
document.querySelector('button').onclick = function(){
nav.classList.toggle('top');
}
button {
width: 100px;
height: 50px;
}
nav {
width: 50vw;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 10px;
background: red;
--d:0.2s;
}
nav > a {
width: 100%;
height: 50px;
transition: .5s transform;
transform: translateY(100%);
opacity: 0.5;
background: lime;
}
nav.top > a {
transform: translateY(0);
}
nav > a:nth-last-child(1) { transition-delay:calc(0 * var(--d));}
nav > a:nth-last-child(2) { transition-delay:calc(1 * var(--d));}
nav > a:nth-last-child(3) { transition-delay:calc(2 * var(--d));}
nav > a:nth-last-child(4) { transition-delay:calc(3 * var(--d));}
nav.top > a:nth-child(1) { transition-delay:calc(0 * var(--d));}
nav.top > a:nth-child(2) { transition-delay:calc(1 * var(--d));}
nav.top > a:nth-child(3) { transition-delay:calc(2 * var(--d));}
nav.top > a:nth-child(4) { transition-delay:calc(3 * var(--d));}
<button>Toggle</button><nav><ahref=''></a><ahref=''></a><ahref=''></a><ahref=''></a></nav>
We can simplify the CSS code by grouping the elements with the same delay:
var nav = document.querySelector('nav');
document.querySelector('button').onclick = function(){
nav.classList.toggle('top');
}
button {
width: 100px;
height: 50px;
}
nav {
width: 50vw;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 10px;
background: red;
--d:0.2s;
}
nav > a {
width: 100%;
height: 50px;
transition: .5s transform;
transform: translateY(100%);
opacity: 0.5;
background: lime;
}
nav.top > a {
transform: translateY(0);
}
nav > a:nth-last-child(1),
nav.top > a:nth-child(1) { transition-delay:calc(0 * var(--d));}
nav > a:nth-last-child(2),
nav.top > a:nth-child(2) { transition-delay:calc(1 * var(--d));}
nav > a:nth-last-child(3),
nav.top > a:nth-child(3){ transition-delay:calc(2 * var(--d));}
nav > a:nth-last-child(4),
nav.top > a:nth-child(4){ transition-delay:calc(3 * var(--d));}
<button>Toggle</button><nav><ahref=''></a><ahref=''></a><ahref=''></a><ahref=''></a></nav>
Solution 2:
This anwer shows a good way to clear all setTimeout
- just add it into each part of the if/else
statement:
document.querySelector('button').onclick = function() {
const
items = document.querySelector('nav').childrenif (items[0].getBoundingClientRect().top >= document.querySelector('nav').getBoundingClientRect().bottom) {
var id = window.setTimeout(() => {}, 0);
while (id--) {
window.clearTimeout(id);
}
// start showing elements, starting from the beginningfor (let i = 0; i < items.length; i++) {
setTimeout(function() {
items[i].style.transform = 'translateY(0)'
}, i * 200)
}
} else {
var id = window.setTimeout(() => {}, 0);
while (id--) {
window.clearTimeout(id);
}
// start hiding elements, starting from the backfor (let i = 0; i < items.length; i++) {
setTimeout(function() {
items[i].style.transform = 'translateY(100%)'
}, (items.length - 1 - i) * 200)
}
}
}
button {
width: 100px;
height: 50px;
}
nav {
width: 50vw;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 10px;
background: red;
}
nav>a {
width: 100%;
height: 50px;
transition: .5s transform;
transform: translateY(100%);
opacity: 0.5;
background: lime;
}
<button>Toggle</button><nav><ahref=''></a><ahref=''></a><ahref=''></a><ahref=''></a></nav>
Post a Comment for "Cancel Pending Settimeouts For Multiple Items In For Loop"