Reputation: 246
How can I time this loop better? I am trying to go through all the div
's in the DOM and transform them over 5s and then remove them. I don't think I am using the transitionend
event properly. I just want to transform one element at a time, remove it and then continue the loop
let els = document.querySelectorAll('div');
els.forEach((x,i) => {
setTimeout(() => {
x.style.transform = 'translate(400%, 400%)';
x.style.transition = 'all 5s ease-in';
x.addEventListener('transitionend', () => {
console.log("transition has ended");
x.remove()
});
}, i * 400);
})
Upvotes: 0
Views: 167
Reputation: 22365
I don't see the point of setTimeOut usage, is it just for launching the transitions?
In this case I prefer to use a button!
let divs = document.querySelectorAll('div')
, btTest = document.querySelector('button')
const elmTransEnd = el => new Promise(rsvl =>
{
const endTrans=e=>{ el.removeEventListener('transitionend', endTrans);rsvl() }
el.addEventListener('transitionend', endTrans);
el.style.transition = 'all 3s ease-in';
el.style.transform = 'translateX(80%)';
});
async function* stepGen(elArr) { yield* elArr; }
async function launchTransitions()
{
for await (let el of stepGen([...divs]))
{
await elmTransEnd(el);
console.log('el', el.textContent, 'done')
el.remove()
}
}
btTest.onclick = _ =>
{
btTest.disabled = true
launchTransitions()
}
<button>test</button>
<div>foo1</div>
<div>foo2</div>
<div>foo3</div>
Upvotes: 0
Reputation: 371049
Since the transition lasts 5 seconds, multiply the i
by 5000, not 400:
let els = document.querySelectorAll('div');
els.forEach((x,i) => {
setTimeout(() => {
x.style.transform = 'translate(400%, 400%)';
x.style.transition = 'all 5s ease-in';
x.addEventListener('transitionend', () => {
console.log("transition has ended");
x.remove()
});
}, i * 5000);
})
<div>foo</div>
<div>foo</div>
<div>foo</div>
A more general approach without knowing the transition duration in advance would be to await a Promise:
let els = document.querySelectorAll('div');
setTimeout(() => {
(async () => {
for (const x of els) {
await new Promise((resolve) => {
x.style.transition = 'all 5s ease-in';
x.style.transform = 'translate(400%, 400%)';
x.addEventListener('transitionend', () => {
console.log("transition has ended");
x.remove()
resolve();
});
});
}
})();
});
<div>foo</div>
<div>foo</div>
<div>foo</div>
Upvotes: 2