gpt4 book ai didi

javascript - 如何使用 Promise 链接 CSS 动画?

转载 作者:行者123 更新时间:2023-12-04 14:45:17 25 4
gpt4 key购买 nike

我想弄清楚如何 Promise工作并使一个 CSS 动画一个接一个地运行。但是它们同时运行......

JS fiddle

let move_boxes = () => {
return new Promise( (resolve, reject) => {
resolve ('boxes moved!')
})
};
let move_box_one = () => {
return new Promise( (resolve, reject) => {
resolve (document.getElementById('div_two').style.animation = 'move 3s forwards')
console.log('box one moved!')
})

}
let move_box_two = () => {
return new Promise( (resolve, reject) => {
resolve (document.getElementById('div_one').style.animation = 'move 3s forwards')
console.log('box two moved!')
})
}

move_boxes().then(() => {
return move_box_one();
}).then(() => {
return move_box_two();
});

最佳答案

与发布的答案相反,我不鼓励使用 window.setTimeout ,因为它不能保证计时器与动画结束事件同步,动画结束事件有时会卸载到 GPU。如果您想更加确定,你应该听 animationend event ,并在回调本身中解决它,即:

let move_box_one = () => {
return new Promise((resolve, reject) => {
const el = document.getElementById('div_one');
const onAnimationEndCb = () => {
el.removeEventListener('animationend', onAnimationEndCb);
resolve();
}

el.addEventListener('animationend', onAnimationEndCb)
el.style.animation = 'move 3s forwards';
});
}

更好的是,由于您为两个盒子编写了一些重复的逻辑,您可以将所有这些抽象成一个返回 promise 的通用函数:
// We can declare a generic helper method for one-time animationend listening
let onceAnimationEnd = (el, animation) => {
return new Promise(resolve => {
const onAnimationEndCb = () => {
el.removeEventListener('animationend', onAnimationEndCb);
resolve();
}
el.addEventListener('animationend', onAnimationEndCb)
el.style.animation = animation;
});
}

let move_box_one = async () => {
const el = document.getElementById('div_one');
await onceAnimationEnd(el, 'move 3s forwards');
}
let move_box_two = async () => {
const el = document.getElementById('div_two');
await onceAnimationEnd(el, 'move 3s forwards');
}

另外,您的 move_boxes功能有点复杂。如果您想异步运行单个盒子移动动画,请将其声明为异步方法并简单地等待单个盒子移动函数调用,即:
let move_boxes = async () => {
await move_box_one();
await move_box_two();
}
move_boxes().then(() => console.log('boxes moved'));

请参阅概念验证示例(或者您可以从原始示例中的 this JSFiddle that I've forked 中查看):

// We can declare a generic helper method for one-time animationend listening
let onceAnimationEnd = (el, animation) => {
return new Promise(resolve => {
const onAnimationEndCb = () => {
el.removeEventListener('animationend', onAnimationEndCb);
resolve();
}
el.addEventListener('animationend', onAnimationEndCb)
el.style.animation = animation;
});
}

let move_box_one = async () => {
const el = document.getElementById('div_one');
await onceAnimationEnd(el, 'move 3s forwards');
}
let move_box_two = async () => {
const el = document.getElementById('div_two');
await onceAnimationEnd(el, 'move 3s forwards');
}

let move_boxes = async () => {
await move_box_one();
await move_box_two();
}
move_boxes().then(() => console.log('boxes moved'));
#div_one {
width: 50px;
height: 50px;
border: 10px solid red;
}

#div_two {
width: 50px;
height: 50px;
border: 10px solid blue;
}

@keyframes move {
100% {
transform: translateX(300px);
}
}

@keyframes down {
100% {
transform: translateY(300px);
}
}
<div id="div_one"></div>
<div id="div_two"></div>

关于javascript - 如何使用 Promise 链接 CSS 动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60683529/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com